小程式 - 驗證碼倒數計時元件

krypton發表於2018-12-26

傳送驗證碼倒數計時的方法很常見,在專案裡面也經常會多次用到,這時就要把倒數計時封裝為元件,需要用到的時候方便使用。

自定義元件

需要封裝一個元件,首先要熟悉小程式自定義元件的文件。官方文件在這裡

倒數計時元件

為了方便描述,我把頁面定義為父元件,把倒數計時元件定義為子元件吧。

首先需要清楚子元件與父元件之間事件的響應方法,例如:子元件響應父元件的事件,子元件修改父元件的data屬性等。

  1. 小程式沒有像Vue裡面的watch模式也沒有computed計算屬性,但是還好小程式properties裡有observer,官方文件說observer表示屬性值被更改時的響應函式,那這樣就好辦了。
  2. 當子元件倒數計時完成之後,需要告訴父元件,子元件已經完成了倒數計時,這裡可以用到方法傳遞的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
      })
    }
  }
  
})
複製程式碼

結語

以上是根據自己公司的需求封裝的倒數計時元件,寫得不夠優雅,只是想記錄一下小程式自定義元件的互相傳值和事件響應。如有更好的方法可以提供下思路。

相關文章