需求描述
因本需求针对投票功能,通过调取接口获取投票功能的结束投票时间(时间可存数据库),即倒计时的结束时间。当然,如果没有获取时间的接口,也可以直接在项目代码中给定结束时间,只不过在结束时间需要改动的情况下需要修改业务代码,不太好维护。
方案制定
- 声明变量(结束投票时间)
data: { timeData: { hour: null, // 时 min: null, // 分 second: null // 秒 }, // 在页面上展示的变量 endTime: '' // 结束投票时间 }
- 获取数据:
- 从接口返回的数据中解构出投票结束时间
- 获取当前时间 (nowTime),使用 new Date().getTime() 获取当前时间戳(以毫秒为单位)
- 将结束时间转换为时间戳
computedTime () { let { endTime, timeData } = this.data const nowTime = new Date().getTime() // 当前时间戳 let end = new Date(endTime).getTime() // 结束时间时间戳 let totalSeconds = (end - nowTime) / 1000 // 从当前时间到结束时间的总秒数 timeData.hour = (Math.floor(totalSeconds / 3600) < 0 ? 0 : Math.floor(totalSeconds / 3600)).toString().padStart(2, '0') timeData.min = (Math.floor((totalSeconds % 3600) / 60) < 0 ? 0 : Math.floor((totalSeconds % 3600) / 60)).toString().padStart(2, '0') timeData.second = (Math.floor(totalSeconds % 60) < 0 ? 0 : Math.floor(totalSeconds % 60)).toString().padStart(2, '0') this.setData({ endTime, timeData }) }, async fetchStartTime () { // 如果是直接在项目代码中给定结束时间,则不需要调用接口 const data = await 用于获取投票结束时间接口 this.setData({ endTime: new Date(data.endTime).getTime() // 从回响数据中结构出endTime,并且完成时间戳转换 // endTime: new Date(this.data.endTime).getTime() //指定结束时间 }) let { timer } = this.data clearInterval(timer) // 及时清除定时器 this.computedTime() // 调用核心处理函数 timer = setInterval(() => { this.computedTime() }, 1000); // 声明定时器,每1s调用一次,页面倒计时实现动态修改 this.setData({ timer }) },
- 计算剩余时间:
- 计算从当前时间到结束时间的总秒数,通过 (结束时间时间戳 - 当前时间戳) / 1000 得到
- 格式化时间:
- 小时:计算剩余的小时数,并确保其为两位数。如果剩余时间小于0,则设置为0。
timeData.hour = (Math.floor(totalSeconds / 3600) < 0 ? 0 : Math.floor(totalSeconds / 3600)).toString().padStart(2, '0')
- 分钟:计算剩余的分钟数,并确保其为两位数。如果剩余时间小于0,则设置为0。
timeData.min = (Math.floor((totalSeconds % 3600) / 60) < 0 ? 0 : Math.floor((totalSeconds % 3600) / 60)).toString().padStart(2, '0')
- 秒:计算剩余的秒数,并确保其为两位数。如果剩余时间小于0,则设置为0。
timeData.second = (Math.floor(totalSeconds % 60) < 0 ? 0 : Math.floor(totalSeconds % 60)).toString().padStart(2, '0')
/**
* targetLength:目标字符串的最小长度。如果原字符串已经等于或超过这个长度,则不会进行填充
* padString(可选):用于填充的字符串,默认为空格。如果 padString 的长度超过了需要填充的长度,它会被截断
* **/
// 在这里 padStart 用于确保小时、分钟和秒数始终为两位数
let _str = str.padStart(targetLength, padString)
完整代码附上
Page({
data: {
timeData: {
hour: null,
min: null,
second: null
},
endTime: '',
},
onShow: function () {
this.fetchStartTime()
},
async fetchStartTime () {
const data = await 用于获取投票结束时间接口
this.setData({
endTime: new Date(data.endTime).getTime()
})
let { timer } = this.data
clearInterval(timer)
this.computedTime()
timer = setInterval(() => {
this.computedTime()
}, 1000);
this.setData({
timer
})
},
onHide () { // 页面触发隐藏事件,及时清除定时器
this.setData({
timer: clearInterval(this.data.timer)
})
},
computedTime () {
let { endTime, timeData } = this.data
const nowTime = new Date().getTime()
let end = new Date(endTime).getTime()
let totalSeconds = (end - nowTime) / 1000
timeData.hour = (Math.floor(totalSeconds / 3600) < 0 ? 0 : Math.floor(totalSeconds / 3600)).toString().padStart(2, '0')
timeData.min = (Math.floor((totalSeconds % 3600) / 60) < 0 ? 0 : Math.floor((totalSeconds % 3600) / 60)).toString().padStart(2, '0')
timeData.second = (Math.floor(totalSeconds % 60) < 0 ? 0 : Math.floor(totalSeconds % 60)).toString().padStart(2, '0')
this.setData({
endTime,
timeData
})
},
})
<view>
<view class="time-item" >{{timeData.hour}}</view>
<view class="radio">: </view>
<view class="time-item">{{timeData.min}}</view>
<view class="radio">:</view>
<view class="time-item" >{{timeData.second}}</view>
</view>
演示(可以脑补动态【bushi hahahahaha】)
小小彩蛋
蜘蛛停下工作,看了一会儿日出。 ---阿巴斯-