结语
以上是根据自己公司的需求封装的倒计时组件,写得不够优雅,只是想记录一下小程序自定义组件的互相传值和事件响应。如有更好的方法可以提供下思路。
发送验证码倒计时的方法很常见,在项目里面也经常会多次用到,这时就要把倒计时封装为组件,需要用到的时候方便使用。
需要封装一个组件,首先要熟悉小程序自定义组件的文档。官方文档在这里
为了方便描述,我把页面定义为父组件,把倒计时组件定义为子组件吧。
首先需要清楚子组件与父组件之间事件的响应方法,例如:子组件响应父组件的事件,子组件修改父组件的data属性等。
小程序没有像Vue里面的watch模式也没有computed计算属性,但是还好小程序properties里有observer,官方文档说observer表示属性值被更改时的响应函数,那这样就好办了。
当子组件倒计时完成之后,需要告诉父组件,子组件已经完成了倒计时,这里可以用到方法传递的e.detail来处理。
countdown.js
Component({ /** * 组件的属性列表 */ properties: { // 是否开始倒计时 start: { type: Boolean, value: false, observer(newVal){ if (newVal === true) { this.countdownFunc() } } } }, /** * 组件的初始数据 */ data: { timerText: '获取验证码' }, /** * 组件的方法列表 */ methods: { /** * 触发页面点击事件 */ _getCountdownEvent(){ this.triggerEvent("getCountdownEvent") }, /** * 触发页面修改data事件 */ _setStartDataEvent() { this.triggerEvent("setStartDataEvent", this.data.start) }, /** * 倒计时 */ countdownFunc() { this.setData({ timerText: 60 }) let target = this let countdownNum = target.data.timerText let timer = setInterval(() => { countdownNum-- target.setData({ timerText: countdownNum }) if (countdownNum == 0) { target.setData({ timerText: '重新发送', start: false }) this._setStartDataEvent() //倒计时为0时,让父组件的start重新设置为false clearInterval(timer) //清除定时器 } }, 1000) } } })
显示的倒计时(timerText)可以根据自己需求重新修改。
countdown.wxml
<view bindtap="_getCountdownEvent">{{timerText}}{{start?'s后重试':''}}</view>
调用组件需要在相应的json文件里面注册,这个我就不说了。
sendRandom.wxml
<countdown id="sendRandom" start="{{start}}" bind:getCountdownEvent="_getCountdownEvent" bind:setStartDataEvent="_setStartDataEvent" > </countdown>
sendRandom.js
Page({ /** * 页面的初始数据 */ data: { start: false }, /** * 点击获取验证码 */ _getCountdownEvent(e) { // todo: 点击获取验证码之后,可以根据自己的需求,通知子组件可以开始倒计时了 // 如: 向后台请求发送验证码的方法,请求成功之后将start设置为true,表示倒计时开始了。 if (this.data.start === true) { return } this.setData({ start: true }) }, /** * 倒计时结束 设置setData为false */ _setStartDataEvent(e){ if (e.detail === false) { this.setData({ start: false }) } } })
以上是根据自己公司的需求封装的倒计时组件,写得不够优雅,只是想记录一下小程序自定义组件的互相传值和事件响应。如有更好的方法可以提供下思路。