需求?
Gin + Vue + Element UI框架中,
我的大屏可视化项目, 大屏页面, 里边写了多个轮询定时器. 离开页面需要清理掉, 要不然切换路由还会在后台运行,
页面是自动缓存状态, 也不存在销毁一说了
所以通过路由router配置中, 页面路由监听中, 进行监听路由变化, 但是也没生效
普通定时器 清除
data() {return {timer: null // 定时器状态}},mounted() {// 消息提醒this.startTimer()},destroyed(){// 离开当前路由后的操作clearInterval(this.timer)timer = null},methods: {/** 查询参数列表 */startTimer() {if (this.timer) clearInterval(this.timer) //清空上一个定时器this.timer = setInterval(() => {// 在定时器回调函数中发起请求this.getList()}, 30000) // 每30秒发送一次请求},}
不生效:
beforeDestroy(){ // 离开当前路由前的操作clearInterval(timer)timer = null
}destroyed(){// 离开当前路由后的操作clearInterval(timer)timer = null
}this.$once('hook:beforeDestroy', () => {// $once一次性监听事件,触发后即关闭// hook 自定义钩子函数clearInterval(timer)timer = null
})建议大家常用this.$once('hook:钩子函数, ()=> {})
其本质上是执行this.$emit()并返回一个callBack()
直接用在创建实例处,也可以用于自定义组件上
如:<Test @hook:mounted="loading = false" @hook:beforeUpdated="loading = true" @hook:updated="loading = false" :data="data" />或:mounted() { const timer = setInterval(() => { ... }, 1000);this.$once('hook:beforeDestroy', () => clearInterval(timer);) }
监听路由变化 清除定时器, 依旧不生效
watch: {//监听路由$route:{handler(oldVal,newVal){// 判断当前页面是要清楚的路由不,单页面应用中使用if (oldVal.path != '/xx/xx/xx') {clearInterval(this.timer)this.timer = null} else {this.Init();this.timer = setInterval(() => {this.Init();}, 1000 * 30)}},deep:true, // 深度监听immediate: true // 使监听在页面加载完成后执行,避免数据无变化或初进页面时监听不执行}
},
解决:
vue项目中,正常情况下,我们在生命周期 destroyed 中关闭即可
一旦页面中使用了keep-alive 进行缓存,此时 destroyed 会失效
需要在 deactivated 钩子函数去关闭,他是 keep-alive 特有的钩子函数
// 开启定时器
activated(){this.start()
},
// 关闭定时器
deactivated(){clearInterval(this.timer)
}
eg: