微信小程序实现倒计时功能(好像有点简单)

106 阅读3分钟

需求描述

因本需求针对投票功能,通过调取接口获取投票功能的结束投票时间(时间可存数据库),即倒计时的结束时间。当然,如果没有获取时间的接口,也可以直接在项目代码中给定结束时间,只不过在结束时间需要改动的情况下需要修改业务代码,不太好维护。

方案制定

  • 声明变量(结束投票时间)
    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】)

a899e2b7626e6cbd572bd05127495a6.jpg

小小彩蛋

蜘蛛停下工作,看了一会儿日出。 ---阿巴斯-

36f8f77f3b758b0bf222340378e9f66.jpg