当前位置: 首页 > news >正文

小程序实现一个 倒计时组件

小程序实现一个 倒计时组件

需求背景

  • 要做一个倒计时,可能是天级别,也可能是日级别,时级别,而且每个有效订单都要用,就做成组件了

效果图

Sep-14-2023 16-16-49.gif

Sep-14-2023 16-54-44.gif

需求分析

  1. 需要一个未来的时间戳,或者在服务度直接下发一个未来到现在时间差,我们只需要做倒计时
  2. 进入页面,看是否已经结束, 如果没结束就调用倒计时函数
  3. 每隔1000,做时间戳(毫秒) -1000。边做tick ,边做时间格式化。
  4. 每次调用前,先清除上一个定时器
  5. 组件销毁的时候,也要清除一下定时器

代码实现

  1. 设置初始值,也是1秒,这里单位时毫秒
const interval = 1000;
  1. 进入页面,初始化完成。开始判断是否结束
lifetimes: {ready() {this.startCountdown();},detached() {clearTimeout(this.timer);},},
startCountdown() {const lastTime = this.initTime(this.properties.expireTime); // 这一步,如果服务端返回了未来到现在的差值,则不需要自己计算时间差了// 如果最终时间 < 1000ms 说明 已经过期了,就不用展示倒计时了.if (lastTime > interval) {// 格式化要展示的数据this.defaultFormat(lastTime);this.setData({isCountOver: true, // 标识可以显示倒计时lastTime, // set lastTime});// 调用倒计时函数,主要的逻辑就是每隔1000ms ,让lastTime - 1000this.tick();}},

初始化时间: 如果服务度返回了时间差,这一步不用处理

//初始化时间
initTime(expireTime) {let lastTime = Number(new Date(expireTime * 1000)) - new Date().getTime();console.log('lastTime', lastTime);return Math.max(lastTime, 0);
},

时间的格式化处理,这里都是固定代码,没什么含量

//默认处理时间格式
defaultFormat(time) {const days = 60 * 60 * 1000 * 24;const hours = 60 * 60 * 1000;const minutes = 60 * 1000;const d = Math.floor(time / days);const h = Math.floor((time % days) / hours);const m = Math.floor((time % hours) / minutes);const s = Math.floor((time % minutes) / 1000);this.setData({d: this.fixedZero(d),h: this.fixedZero(h),m: this.fixedZero(m),s: this.fixedZero(s),});
},
// 格式化时间加0
fixedZero(val) {return val < 10 ? `0${val}` : val;
},

tick 倒计时函数

tick() {let { lastTime } = this.data;this.timer = setTimeout(() => {// 每次定时器之前,先把上一个定时器清除clearTimeout(this.timer);// 如果倒计时结束,这是结束的状态if (lastTime < interval) {this.setData({lastTime: 0,isCountOver: false,});} else {// 如果倒计时正常,则每次 -1000 ,并且格式化时间。再次调用tick,直到倒计时结束lastTime -= 1000;this.setData({lastTime,},() => {this.defaultFormat(lastTime);this.tick();},);}}, interval);},

完整代码

  • 父组件(我这里传了一个比较大的时间戳,2024,10.1结束的时间戳)
<order-time expireTime="{{ 1727712000 }}"><view slot="desc">还剩</view>
</order-time>
  • 子组件 (wxml)
<view wx:if="{{ isCountOver }}" class="timer-wrap"><slot name="desc" /><view class="reset-time"><text wx:if="{{ d != '00' }}"> {{ d }}</text>{{ h }}:{{ m }}:{{ s }}</view>
</view>
<view wx:else class="reset-time"> {{ emptyType === '1' ? '已超时': '' }} </view>
  • 子组件 (js)
let interval = 1000;
Component({options: {multipleSlots: true,},properties: {expireTime: {type: String,},emptyType: {type: String,value: '1',},},lifetimes: {ready() {this.startCountdown();},detached() {clearTimeout(this.timer);},},/*** 组件的初始数据*/data: {d: 0, //天h: 0, //时m: 0, //分s: 0, //秒lastTime: '', //倒计时的时间戳isCountOver: false, // 倒计时是否完成},/*** 组件的方法列表*/methods: {startCountdown() {const lastTime = this.initTime(this.properties.expireTime);if (lastTime > interval) {this.defaultFormat(lastTime);this.setData({isCountOver: true,lastTime,});this.tick();}},//默认处理时间格式defaultFormat(time) {const days = 60 * 60 * 1000 * 24;const hours = 60 * 60 * 1000;const minutes = 60 * 1000;const d = Math.floor(time / days);const h = Math.floor((time % days) / hours);const m = Math.floor((time % hours) / minutes);const s = Math.floor((time % minutes) / 1000);this.setData({d: this.fixedZero(d),h: this.fixedZero(h),m: this.fixedZero(m),s: this.fixedZero(s),});},//定时事件tick() {let { lastTime } = this.data;this.timer = setTimeout(() => {clearTimeout(this.timer);if (lastTime < interval) {this.setData({lastTime: 0,isCountOver: false,});} else {lastTime -= 1000;this.setData({lastTime,},() => {this.defaultFormat(lastTime);this.tick();},);}}, interval);},//初始化时间initTime(expireTime) {let lastTime = Number(new Date(expireTime * 1000)) - new Date().getTime();console.log('lastTime', lastTime);return Math.max(lastTime, 0);},// 格式化时间加0fixedZero(val) {return val < 10 ? `0${val}` : val;},},
});
  • 遇到相关变量,自己更改即可

End: 写作粗陋,有纰漏,建议之处,多多指教~~~

http://www.lryc.cn/news/166932.html

相关文章:

  • 【四万字】网络编程接口 Socket API 解读大全
  • 无涯教程-JavaScript - ISREF函数
  • Android:获取MAC < 安卓系统11 <= 获取UUID
  • 线程的几种状态
  • kubernetes集群yaml文件与kubectl工具
  • python基础语法(三)
  • Haproxy集群与常见的Web集群调度器
  • centos免密登录
  • 学Python的漫画漫步进阶 -- 第十四步
  • OpenCV(四十二):Harris角点检测
  • C++数据结构题:DS 顺序表--连续操作
  • DM@命题公式@主范式的性质和应用@数理逻辑解决数字电路全加器问题
  • 基于微信小程序+Springboot线上租房平台设计和实现【三端实现小程序+WEB响应式用户前端+后端管理】
  • Xilinx FPGA 7系列 GTX/GTH Transceivers (2)--IBERT
  • Python 文件介绍和正则表达式
  • ueditor百度富文本编辑器粘贴后html丢失class和style样式
  • 人脸自动贴国旗
  • 异步FIFO设计
  • 学习python和anaconda的经验
  • 【Linux】多线程【上】
  • 生成式人工智能在高等教育 IT 中的作用
  • 黑龙江省DCMM认证、CSMM认证、CMMM认证、知识产权等政策奖励
  • 腾讯云2023年云服务器优惠活动价格表
  • Sleuth--链路追踪
  • MyBatis初级
  • Spring 学习(二)AOP
  • 笔记1.1 计算机网络基本概念
  • 液压切管机配套用液压泵站比例阀放大器
  • C++ Primer Plus 第七章笔记
  • 常用数据库的 API - 开篇