Vue中实现多个并行倒计时及路由切换清理方案

作者:模板散步时间:2026-10-22 21:11:12浏览:178

本文介绍在Vue环境中实现多个商品并行倒计时的方法。通过统一定时器循环更新数据对象中的时间戳,避免为每个商品创建独立定时器。重点解决切换路由时未结束倒计时仍占用性能的问题,利用destroyed生命周期将剩余时间置零并清理状态,提升用户体验。

多商品并行倒计时需求分析

在处理类似拼团场景时,往往需要为列表中的多个商品分别设置独立的倒计时。起初面对这一需求时,若商品数量较少,直接编写固定变量并创建多个定时器即可解决。

然而,实际业务中的数据是动态变化的。参考主流拼团应用的功能实现,本文基于Vue环境探讨如何实现这一功能。

数据准备与基础方法

首先,我们需要构建用于渲染的静态测试数据,以模拟后端返回的商品列表结构。


data () {
 return {
  list: [ // 准备渲染的数据
   {
    remainTime: 900000, // 距离结束还有多久
    remainTimeStr: '' // 展示文案
   },
   {
    remainTime: 400000,
    remainTimeStr: ''
   },
   {
    remainTime: 60500,
    remainTimeStr: ''
   },
  ]
 }
}

接着,从网络资源中获取一个基础的倒计时计算方法作为参考。


countdowm (timestamp) {
 let self = this
 let timer = setInterval(function () {
  let nowTime = new Date()
  let endTime = new Date(timestamp)
  let t = endTime.getTime() - nowTime.getTime()
  if (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)
   hour = hour < 10 ? '0' + hour : hour
   min = min < 10 ? '0' + min : min
   sec = sec < 10 ? '0' + sec : sec
   let format = ''
   if (day > 0) {
    format = `${day}天${hour}小时${min}分${sec}秒`
   }
   if (day <= 0 && hour > 0) {
    format = `${hour}小时${min}分${sec}秒`
   }
   if (day <= 0 && hour <= 0) {
    format = `${min}分${sec}秒`
   }
   self.content = format
  } else {
   clearInterval(timer)
   self.content = 'over'
  }
 }, 1000)
}

在深入编码前,需梳理清楚整体逻辑流程。

倒计时逻辑优化与实现

核心思路是优化原有的倒计时方法。我们不再依赖获取当前时间与结束时间的差值,而是直接使用距离结束的时间戳。通过一个统一的定时器来并行处理多个倒计时,因此需要对原方法进行改造。

  • 优化后的方法不再需要每次获取当前系统时间。
  • 同时也省去了复杂的时间计算步骤。
  • 由于涉及多个倒计时并行运行,清除定时器的逻辑也需要相应调整,以确保资源正确释放。

countdowm (timestamp) {
 let self = this
 let timer = setInterval(function () {
  let t = timestamp
  if (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)
   day = day < 10 ? '0' + day : day
   hour = hour < 10 ? '0' + hour : hour
   min = min < 10 ? '0' + min : min
   sec = sec < 10 ? '0' + sec : sec
   let format = ''
   format = `${day}天${hour}小时${min}分${sec}秒`
   self.content = format
  } else {
   // clearInterval(timer)
   self.content = 'over'
  }
 }, 1000)
}

完成简化后,将上述思路整合进具体的方法实现中。

在定时器内部执行循环,每次迭代将当前数据中的remainTime时间戳减去1000毫秒(即一秒),从而驱动倒计时更新。


countdown () {
 let self = this
 let timer = setInterval(function () {
  for (let i = 0; i < self.list.length; i++) {
   self.list[i].remainTime -= 1000
   let t = self.list[i].remainTime
   if (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)
    day = day < 10 ? '0' + day : day
    hour = hour < 10 ? '0' + hour : hour
    min = min < 10 ? '0' + min : min
    sec = sec < 10 ? '0' + sec : sec
    let format = ''
    format = `距离结束:<b>${day}</b> 天 <b>${hour}</b> 
时 <b>${min}</b> 分 <b>${sec}</b> 秒`
    self.list[i].remainTimeStr = format
    } else {
    // 进行判断 如果数据内所有的倒计时已经结束,那么结束定时器, 如果没有那么继续执行定时器
    let flag = self.list.every((val, ind) => 
 
val.remainTime <= 0)
    if (flag) clearInterval(timer)
    self.list[i].remainTimeStr = `距离结束:<b>00</b> 天 
<b>00</b> 时 <b>00</b> 分 <b>00</b> 秒` // 结束文案
    }
  }
 }, 1000)
}

路由切换时的资源清理

至此,多个并行定时器的基本功能已实现。但发现一个潜在问题:当用户切换路由时,若倒计时尚未结束,定时器仍在后台运行,这会造成不必要的性能损耗。尽管用户不可见,但为提升浏览体验,需在页面切换时进行处理。具体做法是在Vue的生命周期函数中,将相关数据重置为0,从而停止倒计时逻辑。


destroyed () {
 this.list.forEach((val) => {
  val.remainTime = 0
 })
}

以上即为该技术方案的全部内容,希望能为相关开发者提供借鉴,欢迎继续支持本站获取更多技术分享。

作者最新文章