00:文章简介
本文介绍了在Vue + element-ui中配置计时器的相关案例。
01:计时器种类
js中的计时器分为两种:setInterval(),setTimeout()
1.1:setInterval
该计时器的作用为:按照指定的周期(单位毫秒)来调用函数,该方法会一直执行下去,是个死循环,除非使用clearInterval()来清除函数或关闭浏览器窗口。
setInterval(code, millisec, lang)
code: 必须,要调用的函数,不能带参数
millisec: 必须,以毫秒为单位的时间间隔
lang: 可选,选择语言
例子:
const id=setInterval(foo, 5000) // 开始,每隔5s钟运行一次
clearInterval(id) // 停止
1.2:setTimeout
该计时器的作用为:在指定的时间(单位毫秒)后调用函数,单次执行,若要多次执行,需要使用递归。
setTimeout(code, millisec, lang)
code: 必须,要调用的函数,不能带参数
millisec: 必须,以毫秒为单位的时间间隔
lang: 可选,选择语言
例子:
var num = 0;
function startCount(){
console.log(num)
num += 1;
setTimeout(startCount,1000); //setTimeout是超时调用,使用递归模拟间歇调用
}
setTimeout(startCount,1000); //1s后执行
02:setInterval计时器中使用带参函数
function foo(a, b) {
console.log(a + b)
}
setInterval(foo(1, 2), 3000)
// 此时会运行一次并出现一个错误
internal/validators.js:224
throw new ERR_INVALID_CALLBACK(callback);
^
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
可以使用匿名函数来运行带参数的函数
function foo(a, b) {
console.log(a + b)
}
setInterval(() => {
foo(1, 2)
}, 3000)
这就达到了我们定时调用函数的目的
03:setInterval计时器案例之定时刷新列表内容
在前端项目中,我们经常会遇到需要定时刷新列表内容类似的功能,下面是以vue + element-ui中,table组件定时刷新,并实现☑️后,再刷新会根据上次☑️条目是否存在,保持☑️状态。
3.1:配置table组件
目标:列表是实时动态刷新的,实现条目☑️后,即使列表刷新,也保持☑️状态
思路:使用table原生属性,但selection中不会自动判断里面的条目是否还有效
// 列表内容
<el-table
ref="multipleTable"
:data="hostList"
row-key="mac"
border
style="width: 100%">
<el-table-column type="selection" :reserve-selection="true" width="45"> </el-table-column>
</el-table>
关键属性:
ref: 可以通过this.$refs.refValue去调用该table
row-key: 设置每行的唯一id,选中后,会将选中的row对象存在table.selection属性中,也就是this.$refs.multipleTable.selection
reserve-selection="true": 设置刷新后,重新按照row-key记录的值进行选中
3.2:实现判断逻辑
目标:☑️后,再刷新会根据上次☑️条目是否存在,清除无效条目
思路:在getList方法中,使用数组的循环来对比每一个选中过的值,是否存在于新获取的列表中
async getList() {
const { data: response } = await this.$http.get('test')
if (response.code) {
return this.$message.error(response.message)
}
this.hostList = response.results
if (this.$refs.multipleTable.selection.length !== 0) { // 如果选中列表为空,则不判断
this.$refs.multipleTable.selection.forEach((row) => {
// 遍历选中列表,使用json去判断是否存在,如果存在返回值是索引位置,如果不存在,返回值为-1,则删除掉该元素
if (JSON.stringify(this.hostList).indexOf(JSON.stringify(row)) === -1) {
this.$refs.multipleTable.selection.splice(this.$refs.multipleTable.selection.indexOf(row), 1)
}
})
}
}
3.3:计时器配置
把计时器封装为一个函数,可以通过该函数配置计时器的启动与结束
cycleRunFunc(status, func, time) {
if (status) {
// start == 1
this.intervalID = setInterval(func, time)
} else {
// stop == 0
clearInterval(this.intervalID)
this.$message.success('已停止自动刷新,刷新页面后继续自动刷新')
}
}
// 开启计时器 cycleRunFunc(1, foo, 3000)
// 关闭计时器 cycleRunfunc(0)
3.4:遇到的问题
遇到了:vue路由切换后,计时器仍继续工作,后来根据vue的生命周期,发现可以使用切换时销毁的回调函数来帮助我们在切换路由后,终止计时器的工作。
beforeDestroy() {
if (this.intervalID) {
clearInterval(this.intervalID)
}
},
04:设置多个定时任务
const timerManager = {
// func1: 1 先创建一个记录定时任务ID的对象
}
function cycleFunc(status, func, time) {
const funcName = func.name
if (status) {
// set and record
const intervalID = setInterval(func, time) // 开始运行后,将函数名称作为key,ID作为value存储在上面的对象中
timerManager[funcName] = intervalID
} else {
// clear
console.log('stop start +++++++++++++++++++++++++')
const intervalID = timerManager[funcName] // 删除前,从对象中通过函数名称获取value,也就是id
console.log(intervalID)
clearInterval(intervalID)
delete timerManager[funcName] = undefined
console.log('stop end +++++++++++++++++++++++++')
}
}
function foo1() {
console.log('start 11111')
}
function foo2() {
console.log('start 222222')
}
// 运行模拟函数
cycleFunc(1, foo1, 3000)
cycleFunc(1, foo2, 5000)
// 提前设置好停止函数
function one() {
console.log('foo1 is top')
cycleFunc(0, foo1)
console.log(timerManager)
}
function two() {
console.log('foo2 is top')
cycleFunc(0, foo2)
console.log(timerManager)
}
setTimeout(one,10000); //10s后执行
setTimeout(two,20000); //20s后执行
最后的效果为:
start 11111
start 222222
start 11111
start 11111
foo1 is top
stop start +++++++++++++++++++++++++
stop end +++++++++++++++++++++++++
start 222222
start 222222
foo2 is top
stop start +++++++++++++++++++++++++
stop end +++++++++++++++++++++++++
评论区