微信小程序已经推出一段时间了,官方也提供很多组件,但是有些业务场景,官方组件难免有些捉襟见肘,这时候,就需要自己开发一个自定义组件了。但是微信小程序其实是做了很多限制的,本文记录了开发(踩坑)一个公共登录弹出框组件的过程,仅供参考。
1. 一个组件的组成部分
一个微信小程序有四中格式的文件*.wxml、*.wxss、*.js和*.json,*.json其实是小程序和页面的配置文件,开发组件的时候,就不需要这个了。我这里开发一个登陆弹出框组件,我把组件放在component文件夹下:
| 123456789101112131415 | Wechat-APP/├─app.js├─app.json├─app.wxss├─component/│ └─login-pannel/│ ├─login-pannel.js│ ├─login-pannel.wxml│ └─login-pannel.wxss├─image/├─pages/│ ├─index/│ ├─merchant-detail/│ └─merchant-list/└─utils/ |
可见,组件也是由三个部分组成。
1.1. wxml
首先新建组件的模版,/component/login-pannel/login-pannel.wxml,同时,给定义的模版一个唯一标识template name="loginPannel"/template,代码如下:
| 123456789101112131415 | template name="loginPannel" view class="login-pannel" hidden="{{ isHide }}" view catchtap="__lgpanel_close" class="close-btn"/view view class="form-area" view class="login-inline phone {{ phoneClass }}" input placeholder="请填写手机号码" maxlength="11" type="number" bindinput="__lgpanel_phoneInput" bindfocus="__lgpanel_phoneFocus" bindblur="__lgpanel_phoneBlur" / text catchtap="__lgpanel_sendCode" class="verify-btn"{{ verifyText }}/text /view view class="login-inline vcode {{ vcodeClass }}" input placeholder="请填写验证码" maxlength="4" type="number" bindinput="__lgpanel_vcodeInput" bindfocus="__lgpanel_vcodeFocus" bindblur="__lgpanel_vcodeBlur" / /view /view text catchtap="__lgpanel_login" class="login-btn"注册/登录/text /view/template |
官方提供了模版的概念,同时又给出了两种引用方式:import 和 include。include 方式是将你的模版原封不动的“粘贴”到引用的地方,而我们这里开发的是一个交互组件,势必会碰到数据绑定和事件绑定,所以我们最终引用的时候,使用 import 的形式来使用组件。
1.2. wxss
定义组件的样式,/component/login-pannel/login-pannel.wxss。样式没什么好说的,这里略过。
1.3. js
首先定义组件的构造函数,构造函数主要做两件事:
- 把组件的数据“注入”到页面的data对象中;
- 把组件的事件“合并”到页面对象上。
小程序文档中,关于数据和事件,是这么描述的:
- 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
- WXML 中的动态数据均来自对应 Page 的 data。
- 模板拥有自己的作用域,只能使用 data 传入的数据。
这样,想实现模版的数据绑定,只能想办法把组件上的数据“追加”到页面的 data 对象上去;同理,想实现组件的事件绑定,则需要把组件的事件也“传给”页面函数Page。同时,为了防止影响到其它组件,还要给数据和事件都限定了“命名空间”:
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 | let _compData = { '__lgpanel__.isHide': true, '__lgpanel__.phoneNum': '', '__lgpanel__.verifyCode': '', '__lgpanel__.verifyText': '获取验证码', '__lgpanel__.phoneClass': '', '__lgpanel__.vcodeClass': ''}let _compEvent = { __lgpanel_timer: null, __lgpanel_countDown: 60, __lgpanel_close: function () { clearInterval(this.__lgpanel_timer) this.__lgpanel_countDown = 60 this.setData(_compData) }, __lgpanel_sendCode: function () { if (this.__lgpanel_countDown 60) { return } this.setData({ '__lgpanel__.verifyText': this.__lgpanel_countDown + 's' }) this.__lgpanel_timer = setInterval(() = { this.__lgpanel_countDown-- if (this.__lgpanel_countDown = 0) { clearInterval(this.__lgpanel_timer) this.__lgpanel_countDown = 60 this.setData({ '__lgpanel__.verifyText': '重新获取' }) return } this.setData({ '__lgpanel__.verifyText': this.__lgpanel_countDown + 's' }) }, 1000) typeof this.loginPannel._configs.sendCode == "function" && this.loginPannel._configs.sendCode() }}// 小程序最新版把原型链干掉了。。。换种写法let loginPannel = { show: function(data) { this.__page.setData({'__lgpanel__.isHide': false}) if (data) { Object.assign(this._configs, data) } }}function LoginPannel () { // 定义组件的一些回调 this._configs = { sendCode: null, closeCode: null, login: null } // 拿到当前页面对象 let pages = getCurrentPages() let curPage = pages[pages.length - 1] // 把组件的事件“合并到”页面对象上
版权声明 即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。
最新资讯
|













