本篇博客介紹在微信小程序中實現秒殺功能,本篇博客只介紹微信小程序前端顯示效果,后端接口暫不做介紹,效果圖如下:
實現該功能的難點是定時器 setInterval 的使用
微信小程序官方文檔介紹 setInterval:https://developers.weixin.qq.com/miniprogram/dev/api/base/timer/setInterval.html
在使用完定時器后一定要清除定時器,否則定時器將一直運行,占用程序資源,甚至程序報錯。關於有效清除定時器方法在微信開放社區的討論:https://developers.weixin.qq.com/community/develop/doc/00004485db0170052d6abc12f54400
.wxml代碼
<block wx:if="{{isstart}}"> <view class="top"> <view class="imageview"> <image src="/images/background.png" mode="aspectFit"></image> </view> <view class="top_view"> <view class="top_left_view"> <view style="color:red;height:170rpx;line-height:170rpx;margin-top:40rpx;font-size:28rpx"> ¥<text style="font-size:30px">{{list.Money}}</text> {{list.Name}} </view> <view> {{list.Rules[0]}} </view> <view> {{list.Rules[1]}} </view> </view> <view class="top_right_view"> <text>積分兌換</text> </view> </view> </view> <view class="center"> <view style="font-size:34rpx;">積分搶購{{list.Money}}元{{list.Name}}</view> <view style="color:#358174"> <text style="font-size:32rpx">需{{list.Score}}積分 | </text> <text style="font-size:24rpx">每人限搶1次,您已搶購{{list.GetCount}}次</text> </view> <view class="centerview"> <view class="{{list.State==2?'colorred':'colorgray'}}">{{list.StateStr}}</view> <view><text>剩余</text><text style="color:#358174">{{list.LeftCount}}</text><text>份</text></view> </view> </view> <view class="buttom"> <text wx:for="{{list.Info}}" wx:key="key"> {{item}} </text> </view> <block wx:if="{{list.GetCount!=0}}"> <view class="finished"> 您已搶購成功 </view> </block> <block wx:elif="{{list.State==3}}"> <view class="finished"> {{list.Desc}} </view> </block> <block wx:else> <view class="countdownBox" bindtap="nowbuy"> <block wx:if="{{timeout}}"> {{list.Desc}} </block> <block wx:else> <text>倒計時:</text> <view class="item">{{countdown.hour}}</view> <text>:</text> <view class="item">{{countdown.minute}}</view> <text>:</text> <view class="item">{{countdown.second}}</view> </block> </view> </block> </block> <block wx:else> <view class="nostart"> 暫無搶紅包活動 </view> </block>
.wxss代碼
.top { width: 100%; height: 380rpx; font-size: 24rpx; border-bottom: 1px solid #989898; } .imageview { width: 100%; height: 360rpx; } .imageview image { margin-left: 5%; width: 90%; height: 360rpx; } .top_left_view { width: 45%; height: 360rpx; margin-left: 21%; margin-top: 20rpx; color: #636365; line-height: 1.5em; margin-top: -360rpx; } .colorgray{ color: gray; } .colorred{ color: red; } .top_left_view view { text-align: center; } .top_right_view { border: 1px solid black; width: 4%; color: #B89633; height: 200rpx; font-size: 28rpx; margin-top: -300rpx; margin-left: 86%; } .center { width: 90%; margin-left: 5%; padding: 3% 0; line-height: 1.8em; font-size: 26rpx; border-bottom: 1px solid #989898; } .centerview { display: flex; justify-content: space-between; } .buttom { width: 90%; margin-left: 5%; font-size: 26rpx; color: #989898; } .finished{ width: 90%; margin-left: 5%; height: 85rpx; border-radius: 50rpx; background-color: #999999; position: absolute; bottom: 0; margin-bottom: 50rpx; color: white; text-align: center; line-height: 85rpx; } .countdownBox { width: 90%; margin-left: 5%; height: 85rpx; margin-bottom: 50rpx; background-color: #de2c3a; border-radius: 50rpx; display: flex; justify-content: center; align-items: center; color: #fff; font-size: 30rpx; position: absolute; bottom: 0; } .countdownBox .item{ height: 50rpx; color: #000; box-sizing: border-box; padding: 0rpx 8rpx; display: flex; justify-content: center; align-items: center; font-size: 35rpx; font-weight: 480; margin: 0rpx 10rpx; } .nostart{ text-align: center; margin-top: 200rpx; }
.js代碼
var http = require('../../../utils/request.js'); const app = getApp(); Page({ data: { isnull: false, timeout: false, isClicked: true, isstart: false, countdown: { hour: '00', minute: '00', second: '00', millisecond:'00' }, list: [] }, //開始倒計時 startCountdown: function (millisecond) { var that = this; that.clearinterval(); app.globalData.seckillinterval = null; if (millisecond > 0) { app.globalData.seckillinterval = setInterval(function () { millisecond -= 10; if (millisecond <= 0) { if (app.globalData.seckillinterval != null) { clearInterval(app.globalData.seckillinterval); app.globalData.seckillinterval = null; } that.setData({ countdown: { hour: '00', minute: '00', second: '00', millisecond:'00' }, timeout: true }); that.onShow(); } that.transformRemainTime(millisecond); }, 10); } else { that.setData({ timeout: true }); } }, // 剩余時間(毫秒)處理轉換時間 transformRemainTime: function (millisecond) { var that = this; var countdownObj = that.data.countdown; var seconds = Math.floor(millisecond / 1000) // 小時 countdownObj.hour = that.formatTime(Math.floor(seconds / 3600 % 24)); // 分鍾 countdownObj.minute = that.formatTime(Math.floor(seconds / 60 % 60)); // 秒 countdownObj.second = that.formatTime(Math.floor(seconds % 60)); // 毫秒 countdownObj.millisecond = that.formatTime(Math.floor((millisecond % 1000) / 10)); that.setData({ countdown: countdownObj }); }, //格式化時間為2位 formatTime: function (time) { if (time < 10) return '0' + time; return time; }, //點擊“立即搶” nowbuy: function (e) { var that = this; //狀態是“秒殺中”才執行方法 if (that.data.list.State == 2 && that.data.isClicked) { that.setData({ isClicked: false }) http.postRequest("Skill/Buy", {}, function (res) { if (res.IsOk) { wx.showModal({ title: '提示', content: res.Data.ErrMsg, showCancel: false, success(res) { if (app.globalData.seckillinterval) { clearInterval(app.globalData.seckillinterval); app.globalData.seckillinterval = null } that.onShow(); } }) } }, function (res) {}) //防止重復提交 setTimeout(function () { that.setData({ isClicked: true }) }, 1000) } }, onShow: function () { var that = this; //獲取優惠券信息 http.postRequest("Skill/Index", {}, function (res) { if (res.IsOk) { if (res.Data) { that.setData({ list: res.Data, isstart: true }) that.startCountdown(res.Data.StartTimeLeft) } else { that.setData({ isstart: false }) } } }, function (res) {}) }, //清除計時器 clearinterval: function () { if (app.globalData.seckillinterval) { clearInterval(app.globalData.seckillinterval); app.globalData.seckillinterval = null; } }, onHide: function () { this.clearinterval(); }, onUnload: function () { this.clearinterval(); } })
End!