倒计时组件 还是一个比较常用的功能的;

此处是用微信小程序原生语法实现的一个方案:

功能如下:

指定一个时间戳 endTime , 按当前时间距离时间戳(比当前时间靠前)的秒数来刷新倒计时

可以指定可选参数 offSet , 以秒为单位的最大倒计时秒数。超过这个秒数的不显示倒计时

具体实现:

在 components 目录下新建 countdown 文件夹:

countdown.wxml

用于页面上展示倒计时的view

<!--components/countdown/countdown.wxml-->
<view class="countdown">
  <view class="time">{{end}}</view>
  <view class="time" wx:if="{{show}}">{{minutes}}:{{seconds}}</view>
</view>

countdown.wxss

基本样式

/* components/countdown/countdown.wxss */

.countdown {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: var(--sidebar-font-size,14px);
  line-height: var(--sidebar-line-height,20px);
}

.time {
  text-align: center;
  color: rgba(239, 207, 51, 1);
}

countdown.ts

基本样式


// components/countdown/countdown.ts
Component({

  /**
   * 组件的属性列表
   */
  properties: {
    endTime: {
      type: Number, // 以秒为单位的结束时间
      value: 0
    },
    offSet:{
      type: Number, // 以秒为单位的最大倒计时秒数
      value: 7200
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    hours: '00',
    minutes: '00',
    seconds: '00',
    show: false,  //是否显示倒计时
    end: '在售',  //倒计时前显示的内容或者不显示倒计时的时候当作内容占位符
    intervalId: null 
  },

  /**
   * 组件的方法列表
   */
  methods: {
    fNum:function (num:number) {
        return num < 10 ? '0' + num : num.toString()
    },
    startCountdown: function () {
      console.log('startCountdown', this.properties.endTime)
      const countDownOffset = this.properties.offSet // 7200 秒 = 2 小时
      const that = this

      // 时间戳判定
      function tick() {
        let totalSeconds = that.properties.endTime - Math.floor((new Date().getTime() / 1000));

        if (totalSeconds > 0 && totalSeconds <= countDownOffset) {
          //console.log(totalSeconds)
          that.setData({
            end: '倒计时',
            show: true,
            // hours: Math.floor(totalSeconds / 3600),
            // minutes: Math.floor((totalSeconds % 3600) / 60),
            // 此处因为页面展示空间限制,把小时部分加到分钟去显示
            minutes: that.fNum(Math.floor((totalSeconds % 3600) / 60) + 60 * Math.floor(totalSeconds / 3600)) , 
            seconds: that.fNum(Math.floor(totalSeconds % 60))
          });
        } else if (totalSeconds <= 0) {
          console.warn('倒计时结束')
          if (that.data.intervalId)
            clearInterval(that.data.intervalId)
          if (totalSeconds <= 1){
            that.setData({ end: '已截至', show: false })
          }
          //this.triggerEvent('countdownEnd');
        } else {
          // 如果总秒数超过 countDownOffset ,提示未开始
          that.setData({ end: '在售', show:false })
          console.log("倒计时", totalSeconds - countDownOffset, "秒后开始")
        }
      }

      // 记录倒计时ID
      that.setData({ intervalId: setInterval(tick, 1000) }) 

    }
  },
  lifetimes: {
    ready: function () {
      console.log("run ready", this.properties.endTime)
      if (this.properties.endTime) {
        this.startCountdown()
      } else {
        this.setData({
          end:'在售'
        })
        console.error('endTime 未定义');
      }
    },
    detached: function () {
      console.log("detached, clearInterval ", this.data.intervalId)
      clearInterval(this.data.intervalId);
    }
  },
})

调用示例

<countdown end-time="{{activeEndTime}}" id="countdown" wx:if="{{activeEndTime}}" ></countdown>

activeEndTime 是 page 内的 data