定时器的使用与销毁问题
最近翻阅文档发现在处理边界情况中的程序化的事件侦听器 (opens new window)中有一个较好的写法。除了官网中的例子,是否也可以用于定时器中呢?
模拟场景
我在A页面写一个定时器,让他每秒钟打印一个1,然后跳转到b页面,并且如果再跳转回A页面,此时可以看到,定时器依然在执行。这样是非常消耗性能的。上图:
# 解决方案1:
首先在data函数里面进行定义定时器名称:
data() {
return {
timer: null,
};
},
1
2
3
4
5
2
3
4
5
然后这样使用定时器:
count() {
this.timer = setInterval(() => {
console.log(1);
}, 1000);
}
1
2
3
4
5
2
3
4
5
最后在beforeDestroy()生命周期内清除定时器:
beforeDestroy() {
console.log("定时器即将销毁");
clearInterval(this.timer);
this.timer = null;
},
// 测试用
destroyed() {
console.log("定时器销毁完毕");
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
方案1也是我们比较常用的方法,但有这里有两个潜在的问题,引用官网的话来说就是:
- 它需要在这个组件实例中保存这个 timer,如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。
- 我们的建立代码独立于我们的清理代码,这使得我们比较难于程序化的清理我们建立的所有东西。
# 解决方案2:
该方法是通过$once这个事件侦听器在定义完定时器之后的位置来清除定时器。以下是完整代码:
count() {
this.timer = setInterval(() => {
console.log(1);
}, 1000);
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once("hook:beforeDestroy", () => {
console.log("定时器即将销毁");
clearInterval(this.timer);
});
},
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
类似于其他需要在当前页面使用,离开需要销毁的组件(例如一些第三方库的picker组件等等),都可以使用此方式来解决离开后以后在背后运行的问题。
注意
hook:lifeCycle 的这种通过监听内部事件的方式,并不是 vue 公开暴露的 api,所以存在一定的风险,比如说 vue 的版本更迭,可能会修改这个事件的名称,那么这个时候代码就不能运行了,尽量使用官方暴露的 api,这样官方在版本更新的时候会做出详细的说明。
在线编辑 (opens new window)
上次更新: 2021/11/14, 07:48:46