微信小程式之倒數計時元件

MeloGuo發表於2018-04-07

注:這篇文章內容已經過時,請移步 【重構】微信小程式倒數計時元件 這篇新文章進行閱讀。
注:這篇文章內容已經過時,請移步 【重構】微信小程式倒數計時元件 這篇新文章進行閱讀。
注:這篇文章內容已經過時,請移步 【重構】微信小程式倒數計時元件 這篇新文章進行閱讀。

微信小程式之倒數計時元件
最近在寫活動頁的時候,老大和我說:“小郭,你來寫個倒數計時元件吧!”身為實習生的我立馬將這個任務加到了ToDo當中,然後認真思考起來。當時我的思路是後端傳來一個目標時間,然後前端來計算當前時間和目標時間的時間差。但是大哥卻說:“你這樣可不行。”

那麼為什麼不行呢?大哥告訴我說:“因為使用者可以修改手機時間,來直接到達倒數計時的時間。所以應該通過後端直接返回 一個當前時間與目標時間的時間差。”

然後我修改了系統時間嘗試了一下,發現果然如此!既然這樣就那就只好直接用後端給的時間差了。確定好傳入屬性後我們就來思考元件的具體實現。

確定傳入屬性

整個倒數計時元件只需要一個傳入屬性,也就是時間差。如下:

  properties: {
    initDuration: {
      type: Number,
      value: 0,
      observer: function (newVal, oldVal) {
        // ToDo 初始化倒數計時
      }
    }
  }
複製程式碼

時間處理過程

整個處理過程分割成三個函式,分別為如下:

  methods: {
    /**
     * 計算倒數計時
     * @param {Number} duration [秒數時間差,必填]
     * @return {String} [倒數計時字串]
     */
    _countDown: function (duration) {
      if (duration <= 0) {
        this.setData({
          flag: true
        })
        return undefined
      }
      
      // 計算出傳入秒數是幾小時幾分鐘幾秒
      var seconds = this._format(duration % 60)
      var minutes = Math.floor(duration / 60)
      var hours = this._format(Math.floor(duration / 3600))
      if (minutes >= 60) {
        minutes = minutes % 60
      }
      minutes = this._format(minutes)
      
      var result = `${hours}:${minutes}:${seconds}`
      return result
    },
    
    /**
     * 格式化小於10的時間
     * @param {Number} time [必填]
     * @return {String} [返回時間字串]
     */
    _format: function (time) {
      if (time >= 10) {
        return time
      } else {
        return `0${time}`
      }
    },
    
    /**
     * 執行倒數計時
     * @param {Number} initDuration [傳入時間,必填]
     */
    _runCountDown: function (initDuration) {
      // 首次展示倒數計時
      var countDownTime = this._countDown(initDuration)

      // 每1s執行一次的倒數計時計算
      var timer = setInterval(() => {
        // flag為true也就是傳入_countDown的值小於等於零時
        if (this.data.flag === true) {
          clearInterval(timer)
          return undefined
        }
        var duration = this.data.duration - 1
        var countDownTime = this._countDown(duration)
        this.setData({ duration, countDownTime })
      }, 1000)

      this.setData({ countDownTime, timer })
    },
  }
複製程式碼

初始化倒數計時

如果向元件中傳入了新的initDuration(比如重新整理頁面時),那麼便會呼叫屬性的observer回撥。所以我們需要一個函式來處理倒數計時的初始化執行。

  _initCountDown: function (newVal) {
    if (this.data.timer > 0) {
      clearInterval(this.data.timer)
    }
    this.setData({
      flag: false,
      duration: this.data.initDuration
    })
    this._runCountDown(newVal)
  }
複製程式碼

同時在initDuration屬性的observer回撥函式中呼叫:

  observer: function (newVal) {
    this._initCountDown(newVal)
  }
複製程式碼

這樣基本上一個微信小程式中的倒數計時元件就完成了。使用時在'Page'.json中設定好

  {
    "usingComponents": {
      "count-down": "../components/count-down"
    }
  }
複製程式碼

然後在Page中直接使用,並且傳入初始值就可以了。

結尾

這是第一次實習生活的第一個元件任務,在這裡記錄下來。如果哪裡寫的很爛或者邏輯混亂,還請各位讀者在評論中指出。不怕你罵我,就怕你不理我。謝謝各位。

相關文章