微信小程序倒計時組件實例
下面為大家介紹微信小程序倒計時組件,這一組件主要用來顯示小程序中倒計時的效果,下面為開發(fā)文檔
重構(gòu)舊代碼
在原來的組件中有一個initDuration屬性和3個方法,3個方法分別是countDown,format和runCountDown。
initDuration屬性
首先我們需要三個page屬性來幫助完成接下來的代碼,它們的名字和內(nèi)容如下:
timer: null, // 存儲setInterval的ID flag: false, // 倒計時是否結(jié)束的標志 num: 0 // 過去的秒數(shù) 復(fù)制代碼
在initDuration屬性的新的回調(diào)方法中,我們封裝了clearTimer方法,init初始化方法,并且執(zhí)行倒計時。
initDuration: { type: Number, value: 0, observer: function (newVal) { if (this.timer) { this.clearTimer() } this.init() // 重置num和flag this.runCountDown(newVal) } }, 復(fù)制代碼
一定要注意,當傳入的屬性的值為默認值,例如這里是0時,是不會觸發(fā)observer回調(diào)的。
/** * 初始化函數(shù) */ init: function () { this.flag = false this.num = 0 } /** * 清空計時器 */ clearTimer: function () { clearInterval(this.timer) this.timer = null } 復(fù)制代碼
countDown方法
countDown方法是接受一個參數(shù)為倒計時的秒數(shù),返回一個倒計時的字符串。在這個方法中沒有太大改動,只是改動了一些代碼格式。如下:
/** * 計算倒計時 * @param {Number} duration - 秒數(shù)時間差 * @returns {string} 倒計時的字符串 */ countDown: function (duration) { if (duration <= 0) { this.setFlag(true) // 將flag屬性設(shè)為true return '00:00:00' // 返回默認時間設(shè)置 } 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}` }, 復(fù)制代碼
format方法
format方法的作用很簡單,就是處理小于10的數(shù)字展示問題。
/** * 格式化小于10的數(shù)字 * @param {Number} time - 小于10的數(shù)字 * @returns {string} 格式化后的字符串 */ format: function (time) { return time >= 10 ? time : `0${time}` }, 復(fù)制代碼
runCountDown方法
runCountDown方法中的改動比較大,在原來的代碼中邏輯比較混亂,穿插了許多無關(guān)的代碼,其實應(yīng)該將它們封裝起來達到解耦的目的。
runCountDown: function (initDuration) { // 第一次給倒計時賦值 this.setData({ countDownStr }) this.setCountDownTime(this.countDown(initDuration)) // 每一秒更新一次倒計時 this.timer = setInterval(() => { if (this.flag == true) { // 倒計時結(jié)束 clearInterval(this.timer) return undefined } this.addNum() // this.num += 1 this.setCountDownTime(this._countDown(initDuration - this.num)) }, 1000) }, 復(fù)制代碼
增加新功能
我們原來的倒計時組件是缺乏一些功能的,例如傳入的時間只能是秒數(shù),倒計時結(jié)束后只顯示00:00:00,如果傳入的值是0的話會不進行初始化(這算是Bug了)。所以我們需要加入以下的新功能:
- 支持自定義倒計時結(jié)束后現(xiàn)實的字符串。
- 修復(fù)傳入值為0的Bug。
- 傳入的時間可以是秒數(shù),也可以是UTC時間的字符串。
自定義結(jié)束字符串
在倒計時組件中,展示倒計時字符串的是this.data.countDownTime屬性。所以在結(jié)束時將countDownTime屬性的值設(shè)為傳入的字符串即可。 首先,封裝一個賦值方法
setEndContent: function (countDownTime) { if (countDownTime) { this.setData({ countDownTime }) } } 復(fù)制代碼
接下來為組件新增加一個屬性為 endContent 。
endContent: { type: String, value: '00:00:00' } 復(fù)制代碼
接下來,在倒計時結(jié)束的位置,調(diào)用我們的賦值方法,也就是runCountDown方法的計時器回調(diào)函數(shù)中。
this.timer = setInterval(() => { if (this.flag == true) { clearInterval(this.timer) this.setEndContent(this.properties.endContent) // 設(shè)置結(jié)束字符串 return undefined } this.addNum() this.setCountDownTime(this._countDown(initDuration - this.num)) }, 1000) 復(fù)制代碼
這樣自定義字符串就成功了,在使用組件時傳入默認值即可。
修復(fù)傳入值為0的Bug
這個問題的出現(xiàn)是因為當傳入屬性為默認值時,不會調(diào)用observer回調(diào)函數(shù),所以這時我們需要使用組件的 attached 生命周期函數(shù)。
attached: function () { if (this.properties.initDuration <= 0) { // 如果傳入值為零時不會調(diào)用observer回調(diào),則直接從這里展示倒計時結(jié)束 this.setEndContent(this.properties.endContent) } } 復(fù)制代碼
可以傳入UTC時間字符串
為了簡潔起見,我們就不為組件增加新的屬性了,依然使用initDuration屬性,所以要將其type從Number改為null(小程序的這點不夠強,不能選擇多類型。)。在修改type后我們需要封裝一個將UTC時間字符串解析成倒計時秒數(shù)的方法。
parseDate: function (date) { if (typeof date == 'string') { // 將傳進來的時間減去現(xiàn)在的時間,得到的結(jié)果便和直接傳進數(shù)字值相同 return Math.floor((+new Date(date) / 1000)) - Math.floor((+new Date / 1000)) } return date } 復(fù)制代碼
在observer回調(diào)中調(diào)用時如下:
initDuration: { type: null, observer: function (newVal) { if (this.timer) { this._clearTimer() } this._init() this._runCountDown(this.parseDate(newVal)) // 在這里調(diào)用parseData方法 } } 復(fù)制代碼
HiShop小程序工具提供多類型商城/門店小程序制作,可視化編輯 1秒生成5步上線。通過拖拽、拼接模塊布局小程序商城頁面,所看即所得,只需要美工就能做出精美商城。更多小程序商店請查看:小程序商店