微信小程序倒计时组件

栏目: IOS · Android · 发布时间: 6年前

内容简介:回想在4个月前刚刚进入公司实习时,我封装了一个应用于小程序的倒计时组件。链接在这里:以现在的视角再去看之前的实现可以说是一坨看不下去的烂代码。所以也借此机会,将之前的组件重构一番。

回想在4个月前刚刚进入公司实习时,我封装了一个应用于小程序的倒计时组件。

链接在这里: 微信小程序之倒计时组件

以现在的视角再去看之前的实现可以说是一坨看不下去的烂代码。所以也借此机会,将之前的组件重构一番。

重构旧代码

在原来的组件中有一个initDuration属性和3个方法,3个方法分别是countDown,format和runCountDown。

initDuration属性

首先我们需要三个page属性来帮助完成接下来的代码,它们的名字和内容如下:

timer: null, // 存储setInterval的ID
flag: false, // 倒计时是否结束的标志
num: 0 // 过去的秒数
复制代码

在initDuration属性的新的回调方法中,我们封装了clearTimer方法,init初始化方法,并且执行倒计时。

initDuration: {
  type: Number,
  value: 0,
  observer: function (newVal) {
    if (this.timer) {
      this.clearTimer()
    }
  
    this.init() // 重置num和flag
    this.runCountDown(newVal)
  }
},
复制代码

一定要注意,当传入的属性的值为默认值,例如这里是0时,是不会触发observer回调的。

/**
 * 初始化函数
 */
init: function () {
  this.flag = false
  this.num = 0
}

/**
 * 清空计时器
 */
clearTimer: function () {
  clearInterval(this.timer)
  this.timer = null
}
复制代码

countDown方法

countDown方法是接受一个参数为倒计时的秒数,返回一个倒计时的字符串。在这个方法中没有太大改动,只是改动了一些代码格式。如下:

/**
 * 计算倒计时
 * @param {Number} duration - 秒数时间差
 * @returns {string} 倒计时的字符串
 */
countDown: function (duration) {
  if (duration <= 0) {
    this.setFlag(true) // 将flag属性设为true
    return '00:00:00' // 返回默认时间设置
  }

  let seconds = this._format(duration % 60)
  let minutes = Math.floor(duration / 60)
  minutes = minutes >= 60 ? this._format(minutes % 60) : this._format(minutes)
  let hours = this._format(Math.floor(duration / 3600))

  return `${hours}:${minutes}:${seconds}`
},
复制代码

format方法

format方法的作用很简单,就是处理小于10的数字展示问题。

/**
 * 格式化小于10的数字
 * @param {Number} time - 小于10的数字
 * @returns {string} 格式化后的字符串
 */
format: function (time) {
  return time >= 10 ? time : `0${time}`
},
复制代码

runCountDown方法

runCountDown方法中的改动比较大,在原来的代码中逻辑比较混乱,穿插了许多无关的代码,其实应该将它们封装起来达到解耦的目的。

runCountDown: function (initDuration) {
  // 第一次给倒计时赋值 this.setData({ countDownStr })
  this.setCountDownTime(this.countDown(initDuration))

  // 每一秒更新一次倒计时
  this.timer = setInterval(() => {
    if (this.flag == true) { // 倒计时结束
      clearInterval(this.timer)

      return undefined
    }

    this.addNum() // this.num += 1
    this.setCountDownTime(this._countDown(initDuration - this.num))
  }, 1000)
},
复制代码

增加新功能

我们原来的倒计时组件是缺乏一些功能的,例如传入的时间只能是秒数,倒计时结束后只显示00:00:00,如果传入的值是0的话会不进行初始化(这算是Bug了)。所以我们需要加入以下的新功能:

  • 支持自定义倒计时结束后现实的字符串。
  • 修复传入值为0的Bug。
  • 传入的时间可以是秒数,也可以是UTC时间的字符串。

自定义结束字符串

在倒计时组件中,展示倒计时字符串的是this.data.countDownTime属性。所以在结束时将countDownTime属性的值设为传入的字符串即可。 首先,封装一个赋值方法

setEndContent: function (countDownTime) {
  if (countDownTime) {
    this.setData({ countDownTime })
  }
}
复制代码

接下来为组件新增加一个属性为 endContent

endContent: {
  type: String,
  value: '00:00:00'
}
复制代码

接下来,在倒计时结束的位置,调用我们的赋值方法,也就是runCountDown方法的计时器回调函数中。

this.timer = setInterval(() => {
  if (this.flag == true) {
    clearInterval(this.timer)
    
    this.setEndContent(this.properties.endContent) // 设置结束字符串
    
    return undefined
  }
    
  this.addNum()
  this.setCountDownTime(this._countDown(initDuration - this.num))
}, 1000)
复制代码

这样自定义字符串就成功了,在使用组件时传入默认值即可。

修复传入值为0的Bug

这个问题的出现是因为当传入属性为默认值时,不会调用observer回调函数,所以这时我们需要使用组件的 attached 生命周期函数。

attached: function () {
  if (this.properties.initDuration <= 0) {
    // 如果传入值为零时不会调用observer回调,则直接从这里展示倒计时结束
    this.setEndContent(this.properties.endContent)
  }
}
复制代码

可以传入UTC时间字符串

为了简洁起见,我们就不为组件增加新的属性了,依然使用initDuration属性,所以要将其type从Number改为null(小程序的这点不够强,不能选择多类型。)。在修改type后我们需要封装一个将UTC时间字符串解析成倒计时秒数的方法。

parseDate: function (date) {
  if (typeof date == 'string') {
    // 将传进来的时间减去现在的时间,得到的结果便和直接传进数字值相同
    return Math.floor((+new Date(date) / 1000)) - Math.floor((+new Date / 1000))
  }
  
  return date
}
复制代码

在observer回调中调用时如下:

initDuration: {
  type: null,
  observer: function (newVal) {
    if (this.timer) {
      this._clearTimer()
    }
  
    this._init()
    this._runCountDown(this.parseDate(newVal)) // 在这里调用parseData方法
  }
}
复制代码

总结

在这次重构过程中,我看到了之前代码耦合太严重,仅仅满足了凑合用的情况。如果想要再此基础上增加功能的成本很高,所以将内部逻辑拆分。既方便阅读和理解,也方便日后拓展功能。所以重构后我们便增加了两个新功能,希望这边文章可以帮助大家。

倒计时组件代码: github.com/MeloGuo/wxm…

可将'count-down'文件夹直接copy到项目目录下使用。

欢迎喜欢、关注、star、fork,当然也欢迎pr、issue.


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

金融计算与建模

金融计算与建模

朱世武 / 清华大学 / 2007-8 / 40.00元

《金融计算与建模:理论、算法与SAS程序》全书分为4大模块:1-9章为金融学基础指标计算模块;10-12章为股票定价模块;13-18章为风险度量模块;19-23章为固定收益定价模块。每一模块的内容一般由三部分组成:金融理论与模型、算法实现及计算程序。其中,算法实现与计算程序全部以中国金融市场的实际问题为应用背景而设计。《金融计算与建模:理论、算法与SAS程序》不仅展现了应用SAS软件的技术,同时也......一起来看看 《金融计算与建模》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具