一般情况下清除定时器
export default {
data(){
return {
timer:null // 接收定时器返回值
}
},
mounted(){
this.timer = setInterval(() => {
console.log('开始定时器')
},1000)
},
beforeDestory(){
clearInterval(this.timer)
}
}
这段代码是最常见的,也是我平时写的,每次写都不会考虑很多,总觉得这样就可以了,但是其中可以发现几个不好的问题:
- clearInterval后没有清空timer为null
- 开启定时器和清除定时器的代码分散开在两个地方,有损可读性/维护性,用大大大佬的话说,这使得我们比较难于程序化地清理我们建立的东西
- timer被定义在data里,实际上timer不需要什么响应操作,定义在data里是没必要的,反而造成性能浪费。
优化清除定时器
export default {
data(){
return {}
},
mounted(){
let timer =setInterval(() => {
console.log('开始定时器')
},1000)
this.$once('hook:beforeDestory',() => {
clearInterval(timer)
timer=null
})
}
}
这里使用hook监听beforeDestroy生命周期,这样timer只需被定义在生命周期里,以上的问题就全部解决了。
衍生问题:beforeDestroy是否会不触发?
当路由使用keep-alive缓存时是不走beforeDestroy生命周期的,所以实际上定时器没有被清除掉。我们要借助activated和deactivated这两个钩子:
export default {
data(){
return {}
},
mounted(){
let timer=setInterval(() => {
console.log('开启定时器')
},1000)
this.$on('hook:activated',() => {
// 避免重复开启定时器
if(timer===null){
timer=setInterval(() => {
console.log('开启定时器')
},1000)
}
})
this.$on('hook:deactivated',() => {
clearInterval(timer)
timer=null
})
}
}
这里可以看出,将on,是因为缓存的原因,不然执行一次后就不会触发了。