参考地址:https://www.cnblogs.com/zyfenblog/p/11104053.html
参考地址:https://www.dazhuanlan.com/2019/12/09/5dedc6f6d756b/
参考地址:https://blog.csdn.net/my_atlassian_yhl/article/details/81166488

我们先看下最后实现的效果

GIF.gif

  1. 进入秒杀页面,初始化倒计时都是00天00时00分00秒
  2. 计算倒计时,判断当前时间是否小于倒计时开始时间,如果小于则显示倒计时,否则显示活动进行中,当活动结束时后台就会把对应商品清除
  3. 跳转到下一个页面不清空倒计时,返回首页时清空倒计时,再进入秒杀页面时重新初始化倒计时(因为重新获取了列表数据)

    思路:

  4. 核心是加载列表数据之后,统一维护一个倒计时,伪造同时进行倒计时,每秒钟为这个数组中的每一个时间减一秒

  5. 如果所有的列表倒计时都结束了,那就清除倒计时
  6. 下拉刷新需要重新获取数据,这个时候需要清除倒计时
  7. 倒计时存放到app.js全局数据中,这样可以在别的页面清除倒计时

    具体实现:

    1. // app.js
    2. App({
    3. globalData: {
    4. seckillTimer: null, // 秒杀计时器
    5. },
    6. )

    ```javascript // 具体实现页面 onLoad: function (options) { // 进入页面请求列表数据 this.seckillInfoPage() }, seckillInfoPage() { wx.showLoading(); app.api.seckillInfoPage(Object.assign( {}, this.data.page, util.filterForm(this.data.parameter) )) .then(res => {

    1. let seckillInfoList = res.data.records
    2. // 请求到的分页列表数据
    3. let list = [...this.data.seckillInfoList, ...seckillInfoList]
    4. console.log(list);
    5. list.map(item => { // 给每个列表项初始化倒计时
    6. item.validBeginStr = `00天00时00分00秒`
    7. })
    8. // 先更新数据进行显示,这个时候可能倒计时正在计算
    9. this.setData({
    10. seckillInfoList: list
    11. })
    12. // 开始计算倒计时
    13. this.countdown()

    }) },

    // 倒计时(核心方法) countdown() { let that = this let list = this.data.seckillInfoList app.globalData.seckillTimer = setInterval(function () { for (let i = 0; i < list.length; i++) {

    1. // console.log(list[i]);
    2. let nowDate = new Date().getTime()
    3. let t = list[i].validBegin - nowDate
    4. t -= 1000
    5. if (t > 0) {
    6. let day = Math.floor(t / 86400000)
    7. let hour = Math.floor((t / 3600000) % 24)
    8. let min = Math.floor((t / 60000) % 60)
    9. let sec = Math.floor((t / 1000) % 60)
    10. /* var day = parseInt(t / 1000 / 60 / 60 / 24, 10)
    11. var hour = parseInt(t / 1000 / 60 / 60 % 24, 10)
    12. var min = parseInt(t / 1000 / 60 % 60, 10)
    13. var sec = parseInt(t / 1000 % 60, 10) */
    14. day = day < 10 ? '0' + day : day
    15. hour = hour < 10 ? '0' + hour : hour
    16. min = min < 10 ? '0' + min : min
    17. sec = sec < 10 ? '0' + sec : sec
    18. let format = ''
    19. format = `${day}天${hour}时${min}分${sec}秒`
    20. list[i].validBeginStr = format
    21. } else {
    22. // 进行判断 如果数据内所有的倒计时已经结束,那么结束定时器, 如果没有那么继续执行定时器
    23. let flag = list.every((val, ind) => val.validBegin <= 0)
    24. if (flag) clearInterval(app.globalData.seckillTimer)
    25. list[i].validBeginStr = `秒杀进行中` // 结束文案
    26. }

    } wx.hideLoading(); that.setData({ //重新更新列表

    1. seckillInfoList: list

    }) }, 1000) },
    refresh() { this.setData({ loadmore: true, seckillInfoList: [],

  1. ['page.current']: 1
  2. })
  3. // 列表下拉刷新时,清除倒计时
  4. clearInterval(app.globalData.seckillTimer)
  5. this.seckillInfoPage()

}, onPullDownRefresh() { // 显示顶部刷新图标 wx.showNavigationBarLoading() this.refresh() // 隐藏导航栏加载框 wx.hideNavigationBarLoading() // 停止下拉动作 wx.stopPullDownRefresh() }

  1. ```javascript
  2. // home.js
  3. const app = getApp()
  4. Page({
  5. onShow() {
  6. // 每次进入首页,认为是重新进入应用,清空倒计时,
  7. if (app.globalData.seckillTimer) {
  8. clearInterval(app.globalData.seckillTimer)
  9. }
  10. },
  11. })
  1. <wxs module="dateUtil" src="../../../utils/dateUtil.wxs"></wxs>
  2. <view class="cu-card article no-card">
  3. <view class="cu-item" wx:for="{{ seckillInfoList }}" wx:key="index">
  4. <view class="content">
  5. <view class="card_left margin-right-sm">
  6. <image src="{{item.picUrl}}" mode="aspectFill" class="row-img margin-top-xs" />
  7. // 循环显示倒计时
  8. <view class="countdown">{{item.validBeginStr}}</view>
  9. </view>
  10. <view class="desc row-info solid-bottom padding-bottom">
  11. <view class="text-black margin-top-sm overflow-2">{{item.name}}</view>
  12. <view class="flex justify-start margin-top-sm">
  13. <view class="text-price text-bold text-red">{{item.seckillPrice}}</view>
  14. <view class="text-price text-decorat text-sm text-gray margin-left-sm">{{item.goodsSku.salesPrice}}</view>
  15. <view class="cu-tag bg-red radius sm margin-left" wx:if="{{item.goodsSpu.freightTemplat.type == '2'}}">包邮</view>
  16. </view>
  17. <view class="flex justify-end margin-top-sm">
  18. <view class="text-sm text-gray margin-left-sm">已有{{item.launchNum}}人参与</view>
  19. </view>
  20. <view class="flex justify-center margin-top">
  21. <navigator class="cu-btn round bg-red" hover-class="none" url="/pages/seckill/seckill-detail/index?id={{item.id}}">立刻秒杀</navigator>
  22. </view>
  23. </view>
  24. </view>
  25. </view>
  26. </view>
  27. <view wx:if="{{seckillInfoList.length}}" class="cu-load bg-gray {{loadmore?'loading':'over'}}"></view>