参考地址: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
我们先看下最后实现的效果

- 进入秒杀页面,初始化倒计时都是00天00时00分00秒
- 计算倒计时,判断当前时间是否小于倒计时开始时间,如果小于则显示倒计时,否则显示活动进行中,当活动结束时后台就会把对应商品清除
跳转到下一个页面不清空倒计时,返回首页时清空倒计时,再进入秒杀页面时重新初始化倒计时(因为重新获取了列表数据)
思路:
核心是加载列表数据之后,统一维护一个倒计时,伪造同时进行倒计时,每秒钟为这个数组中的每一个时间减一秒
- 如果所有的列表倒计时都结束了,那就清除倒计时
- 下拉刷新需要重新获取数据,这个时候需要清除倒计时
倒计时存放到app.js全局数据中,这样可以在别的页面清除倒计时
具体实现:
// app.jsApp({globalData: {seckillTimer: null, // 秒杀计时器},)
```javascript // 具体实现页面 onLoad: function (options) { // 进入页面请求列表数据 this.seckillInfoPage() }, seckillInfoPage() { wx.showLoading(); app.api.seckillInfoPage(Object.assign( {}, this.data.page, util.filterForm(this.data.parameter) )) .then(res => {
let seckillInfoList = res.data.records// 请求到的分页列表数据let list = [...this.data.seckillInfoList, ...seckillInfoList]console.log(list);list.map(item => { // 给每个列表项初始化倒计时item.validBeginStr = `00天00时00分00秒`})// 先更新数据进行显示,这个时候可能倒计时正在计算this.setData({seckillInfoList: list})// 开始计算倒计时this.countdown()
}) },
// 倒计时(核心方法) countdown() { let that = this let list = this.data.seckillInfoList app.globalData.seckillTimer = setInterval(function () { for (let i = 0; i < list.length; i++) {
// console.log(list[i]);let nowDate = new Date().getTime()let t = list[i].validBegin - nowDatet -= 1000if (t > 0) {let day = Math.floor(t / 86400000)let hour = Math.floor((t / 3600000) % 24)let min = Math.floor((t / 60000) % 60)let sec = Math.floor((t / 1000) % 60)/* var day = parseInt(t / 1000 / 60 / 60 / 24, 10)var hour = parseInt(t / 1000 / 60 / 60 % 24, 10)var min = parseInt(t / 1000 / 60 % 60, 10)var sec = parseInt(t / 1000 % 60, 10) */day = day < 10 ? '0' + day : dayhour = hour < 10 ? '0' + hour : hourmin = min < 10 ? '0' + min : minsec = sec < 10 ? '0' + sec : seclet format = ''format = `${day}天${hour}时${min}分${sec}秒`list[i].validBeginStr = format} else {// 进行判断 如果数据内所有的倒计时已经结束,那么结束定时器, 如果没有那么继续执行定时器let flag = list.every((val, ind) => val.validBegin <= 0)if (flag) clearInterval(app.globalData.seckillTimer)list[i].validBeginStr = `秒杀进行中` // 结束文案}
} wx.hideLoading(); that.setData({ //重新更新列表
seckillInfoList: list
}) }, 1000) },
refresh() { this.setData({ loadmore: true, seckillInfoList: [],
['page.current']: 1})// 列表下拉刷新时,清除倒计时clearInterval(app.globalData.seckillTimer)this.seckillInfoPage()
}, onPullDownRefresh() { // 显示顶部刷新图标 wx.showNavigationBarLoading() this.refresh() // 隐藏导航栏加载框 wx.hideNavigationBarLoading() // 停止下拉动作 wx.stopPullDownRefresh() }
```javascript// home.jsconst app = getApp()Page({onShow() {// 每次进入首页,认为是重新进入应用,清空倒计时,if (app.globalData.seckillTimer) {clearInterval(app.globalData.seckillTimer)}},})
<wxs module="dateUtil" src="../../../utils/dateUtil.wxs"></wxs><view class="cu-card article no-card"><view class="cu-item" wx:for="{{ seckillInfoList }}" wx:key="index"><view class="content"><view class="card_left margin-right-sm"><image src="{{item.picUrl}}" mode="aspectFill" class="row-img margin-top-xs" />// 循环显示倒计时<view class="countdown">{{item.validBeginStr}}</view></view><view class="desc row-info solid-bottom padding-bottom"><view class="text-black margin-top-sm overflow-2">{{item.name}}</view><view class="flex justify-start margin-top-sm"><view class="text-price text-bold text-red">{{item.seckillPrice}}</view><view class="text-price text-decorat text-sm text-gray margin-left-sm">{{item.goodsSku.salesPrice}}</view><view class="cu-tag bg-red radius sm margin-left" wx:if="{{item.goodsSpu.freightTemplat.type == '2'}}">包邮</view></view><view class="flex justify-end margin-top-sm"><view class="text-sm text-gray margin-left-sm">已有{{item.launchNum}}人参与</view></view><view class="flex justify-center margin-top"><navigator class="cu-btn round bg-red" hover-class="none" url="/pages/seckill/seckill-detail/index?id={{item.id}}">立刻秒杀</navigator></view></view></view></view></view><view wx:if="{{seckillInfoList.length}}" class="cu-load bg-gray {{loadmore?'loading':'over'}}"></view>
