前言

项目中有下图这样一个显示倒计时的需求,需要实现;
一开始想法是需要接口返回 到期时间戳 减去 客户端当前时间 ,然后计算出要显示 倒计时剩余时间 ;最后感觉用客户端时间会不准确,可能会出现服务器时间已经显示到期,但是客户端还差几分钟的情况,所以和后端商量他那边计算 到期时间戳 - 服务器时间戳 = 服务器待付款时间差,最后把服务器待付款时间差的时间戳返给我,我再对这个时间戳进行处理,生成下面设计图这种时间样式
在这里插入图片描述

具体步骤

  1. 和后端商量他那边计算 到期时间戳 - 服务器时间戳 = 服务器待付款时间差,最后把服务器待付款时间差的时间戳返给我
  2. 对返回的时间戳进行处理,对应天,时,分
  3. 递归的方式使用setTimeOut(),每60s调用runBack方法一次,显示动态时间效果
  4. 最后在 实例销毁前清除 setTimeOut() 定时器,防止内存泄漏

代码

最后附上自己写的倒计时代码

<template>
  <div class="root">
    <div class="time" v-if="resData.status !== 3">
      <span>剩余</span>
      <span v-if="day != '00'">{{ day }}</span>
      <span>{{ hour }}小时</span>
      <span>{{ minute }}分钟</span>
      <span>{{ resData.status === 1 ? '自动关闭' : '自动收货' }}</span>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      day: '00',
      hour: '00',
      minute: '00',
      timer: 0
    }
  },
  methods: {
    getOrderDetail () {
      signApi['orderDetail']({
        orderSn: this.$route.query.order_sn
      })
        .then(res => {
          if (res.data.code === 200) {
            this.resData = res.data.data
            let temp = res.data.data

            let payDiff = temp.pay_off_time // status=1 表示待支付 服务器待付款时间差
            let deliverDiff = temp.delivery_finish_time // status=2 表示待收货 服务器待收货时间差  (只会返回其中一种状态)
            if (payDiff) {
              this.countdown(payDiff)
            } else if (deliverDiff) {
              this.countdown(deliverDiff)
            }
          }
        })
        .catch(error => {
          console.log(error)
        })
    },
    // 倒计时
    countdown (diff) {
      let diffTime = diff * 1000 // 时间差 s转为ms
      this.runBack(diffTime)
    },
    runBack (diff) {
      if (diff > 0) {
        let dd = parseInt((diff / 1000 / 60 / 60 / 24) % 1)
        let hh = parseInt((diff / 1000 / 60 / 60) % 24)
        let mm = parseInt((diff / 1000 / 60) % 60)

        this.day = dd > 9 ? dd : '0' + dd
        this.hour = hh > 9 ? hh : '0' + hh
        this.minute = mm > 9 ? mm : '0' + mm

        // 递归的方式使用setTimeOut(),相当于setInterval(),显示动态时间效果
        // setTimeOut()方法会返回一个数值ID,便于清除定时器时使用
        this.timer = setTimeout(() => {
          diff -= 60000
          this.runBack(diff)
        }, 60000)
      } else {
        // 订单已过期
        this.day = '00'
        this.hour = '00'
        this.minute = '00'
      }
    }
  },
  mounted () {
    this.getOrderDetail()
  },
  // 销毁前清除定时器,防止内存泄漏
  beforeDestroy () {
    clearTimeout(this.timer)
  }
}
</script>

<style></style>

关于 setTimeout和setInterval

在这里插入图片描述

可参考:
支付订单中未付款倒计时 讲的比较细致
vue实现时间倒计时功能 有settimeout递归调用函数
web前端处理订单待支付倒计时计算显示问题

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐