前言:
由于工作项目需求,需要实现功能:在一个展示设备信息的设备列表中,如果设备处于警告状态,则该设备会有一个发生警告的时间点,需要根据时间点计算发生警告至今的时间,且要求是动态的(即每秒刷新一次,类似时钟)。
之前做过根据一个时间点来计时的功能,但那是只有一项的情况。所以,难点是在v-for列表中实现多项计时。经过网查和摸索,实现效果,记录一下。
一、直接上代码
data() {
return {
deviceList: [],
timer: ''
}
},
1、请求接口拿到设备列表后处理数据
getDeviceList().then(res => {
let deviceList = res.rows || []
this.deviceList = deviceList.map(item => {
// 该参数有值则为警告状态设备,计算发生警告至今的时间(单位毫秒),用于计时
if (item.alarmTime) {
item.count_time = new Date().getTime() - new Date(item.alarmTime).getTime()
}
return item
})
// 执行定时器的函数,定时器周期为1秒
this.beginTimer()
})
2、设置定时器,每秒刷新一次设备列表deviceList的数据。
关键点:一定要重新给deviceList赋值,否则页面不会刷新。下面的定时器中map返回的是一个新数组。
// 定时器 设备列表里的警告设备,count_time每秒加1000毫秒,以刷新页面计时
beginTimer() {
this.timer = setInterval(() => {
this.deviceList = this.deviceList.map(item => {
// 有count_time参数的则为警告设备
if (item.count_time) item.count_time = item.count_time + 1000
return item
})
// console.log(this.deviceList)
}, 1000)
}
3、现在每个警告设备里都有一个count_time参数实时计时,单位是毫秒,通过过滤器转换成时钟格式。
filters: {
// 把毫秒数换算成时分秒
timeFilter(time) {
if (time >= 0) {
let h = Math.floor(time / 1000 / 60 / 60)
h = h < 10 ? '0' + h : h
let m = Math.floor((time / 1000 / 60) % 60);
m = m < 10 ? '0' + m : m
let s = Math.floor((time / 1000) % 60);
s = s < 10 ? '0' + s : s
return `${h}:${m}:${s}`
}
else return ''
}
},
4、页面展示
<view class="device-list">
<view class="device-item" v-for="(item, index) in deviceList" :key="index">
<!-- 警告设备才有count_time -->
<view v-if="item.count_time">{{ item.count_time | timeFilter }}</view>
</view>
</view>
5、卸载页面时清除定时器
// 监听页面卸载,清除计时器
onUnload() {
clearInterval(this.timer)
},
已实现预想效果。
记录于2021/09/04。