Vue2 里如何优雅的清除一个定时器
绝大多数人清除定时器的方法
<script>
export default {
data() {
return {
timer: null
}
},
mounted() {
this.timer = setInterval(() => {
console.log('我是定时器')
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
这样写的缺点
上面是一段常见的代码
至少我身边的好几个小伙伴都是这么写的,这里存在3个不优雅的问题:
第1个:clearInterval 后没有清空 timer 为 null。
第2个:开启定时器和清除定时器的代码分散开在两个地方,可读性/维护性下降.
第3个:timer 被定义在 data 里,实际上 timer 不需要什么响应式操作,定义在 data 里是没必要的,反而造成性能浪费。
使用 hook 监听 beforeDestroy 生命
export default {
data() {
return {
}
},
mounted() {
let timer = setInterval(() => {
console.log('---定时器在触发---')
}, 1000)
this.$once('hook:beforeDestroy', () => {
console.log('这里使用 hook 监听 beforeDestroy 生命')
clearInterval(timer)
timer = null
})
},
methods: {
backPage() {
this.$router.back()
}
}
}
</script>
这里使用 hook 监听 beforeDestroy 生命周期.
这样 timer 只需被定义在生命周期里,以上的问题就全部解决了。
ps: hook 是可以监听vue的生命周期的。
如果项目中使用了-- keep-alive 如何解决
在后台系统中,我们常常会设置页面缓存。
而当路由被 keep-alive 缓存时是不走 beforeDestroy 生命周期的。
此时将不能清除定时器。这时候我们需要借助 activated 和 deactivated 这两个生钩子:
activated 是进入页面的时候被触发
deactivated 是离开页面的时候会被触发,我们将在这个页面清除定时器
<script>
export default {
mounted() {
// 开启定时器
let timer = setInterval(() => {
console.log('---定时器在触发---')
}, 1000)
//这下面的代码不可以省略
this.$on('hook:activated', () => {
if (timer === null) { // 避免重复开启定时器
timer = setInterval(() => {
console.log('setInterval')
}, 1000)
}
})
this.$on('hook:deactivated', () => {
clearInterval(timer)
timer = null
})
}
}
<script>
这里需要注意一下,由于缓存原因.
所以需要用 $on 而不是 $once
因此$once 只会触发一次的哈
$on 和 $once 的区别
Api 中的解释:
$on(eventName:string|Array, callback) 监听事件
监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。
回调函数会接收所有传入事件触发函数的额外参数。
$once(eventName: string, callback) 监听事件
监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
vue3中如何使用
在vue3中 $on进行监听,$off取消监听 和 $once 实例方法已被移除.
所以无法优雅的清除定时器了。
Vue2 里如何优雅的清除一个定时器的更多相关文章
- Linux使用一个定时器实现设置任意数量定时器功能【转】
转自:https://www.jb51.net/article/120748.htm 为什么需要这个功能,因为大多数计算机软件时钟系统通常只能有一个时钟触发一次中断.当运行多个任务时,我们会想要多个定 ...
- ASP.NET中设置一个定时器来定时更新 转
asp.net 定时器 比较少用, 中国红木网这是一个相当实用的功能,有了RSS博客镜像,就不需要在多处同时发布博客日志了.比如你同时在新浪上有自己的博客,又同时有自己的个人博客站点,那么你只需要在 ...
- js清除未知定时器的方法
js清除未知定时器的方法 在需要有实时性更新数据的项目中,我们经常会用到很多定时器,我们可能需要一个可以一次性清除所有定时器的方法,并且不通过指定ID一个一个去清除,以下提供两种解决方案: 1.定 ...
- JS---另一个定时器:一次性的
之前学的定时器:setInterval和清除定时器 clearInterval(定时器id); //常用的,反复的执行 window.setInterval(function () { alert(& ...
- 注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式
注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式 这个坑,必须要注意呀, 比如在用ListView的时候,如果在List_ ...
- m个苹果放在n个筐里,每个筐至少一个,所有的筐都一样,有多少种放法
package com.study; import java.io.BufferedReader; import java.io.IOException; import java.io.InputSt ...
- Eclipse里的代码光标变成一个黑色块
以前经常在编写程序是不知到碰到键盘上的那个键了,或是那几个组合键了,使得Eclipse里的代码光标变成一个黑色块:在这个状态下,光标不在活动自如,只能一直往后写代码,就不想平时的 " | & ...
- 如何优雅的封装一个DOM事件库
1.DOM0级事件和DOM2级事件 DOM 0级事件是元素内的一个私有属性:div.onclick = function () {},对一个私有属性赋值(在该事件上绑定一个方法).由此可知DOM 0级 ...
- Spring容器初始化的时候如何添加一个定时器?
昨天遇到这个问题,在项目启动的时候添加一个定时器隔一段时间扫描有没有定时发送的邮件(当然也可以是你自己的业务逻辑),也在网上找了资料,加上自己的修改,终于成功了.所以来做个记录. 1.ServletC ...
- 如何在在页面中清除一个已知的cookie?
前些天在写一个项目的时候,使用cookie来存储一些用户数据,在用户登出时需要清理以往的数据,对于一个初学者来说,我需要学习如何清除一个已知的cookie. 首先,引入两个js文件: 1.jquery ...
随机推荐
- 技术架构+应用场景揭秘,为什么高斯Redis比开源香?
摘要:高斯Redis即保留了开源Redis的能力,同时凭借其存算分离的架构,在成本.稳定性.可靠性.一致性等方面做出了新的突破,也更加适用于当下数据规模庞大的互联网业务. 本文分享自华为云社区< ...
- vue2升级vue3:composition api中监听路由参数改变
vue2 的watch回顾 我们先回顾一下vue2中watch <watch性能优化:vue watch对象键值说明-immediate属性详解> <vue中methods/watc ...
- Appuploader工具让ipa上传到App Store 的最新流程和步骤
苹果官方提供的工具xcode上架ipa非常复杂麻烦.用appuploader 可以在 mac 和windows 上制作管理 证书 ,无需钥匙串工具 条件:1.以Windows为例,创建app打包i ...
- 开心档之MySQL 导入数据
MySQL 导入数据 本章节我们为大家介绍几种简单的 MySQL 导入数据命令. 1.mysql 命令导入 使用 mysql 命令导入语法格式为: mysql -u用户名 -p密码 < 要导入的 ...
- 如何删除PPT中工具栏口袋动画
口袋动画官网无法打开 http://www.papocket.com/ 插件无法使用 卸载 在[程序和功能]中卸载后,打开PPT,菜单还是存在 选项--加载项,点击以p开头的一串代码(com加载项), ...
- 大数据 - DWD&DIM 业务数据
业务数据的变化,我们可以通过 FlinkCDC 采集到,但是 FlinkCDC 是把全部数据统一写入一个 Topic 中, 这些数据包括事实数据,也包含维度数据,这样显然不利于日后的数据处理,所以这个 ...
- WCF 使用动态代理精简代码架构 (WCF动态调用)
使用Castle.Core.dll实现,核心代码是使用Castle.DynamicProxy.ProxyGenerator类的CreateInterfaceProxyWithoutTarget方法动态 ...
- 一、redis单例安装(linux)
系列导航 一.redis单例安装(linux) 二.redis主从环境搭建 三.redis集群搭建 四.redis增加密码验证 五.java操作redis 环境:centos7.5需要的安装包: re ...
- mybatis-plus-QueryWrapper like的用法
mybatis-plus 中想写like的语句 一.直接用 QueryWrapper 中的 like String deptLevelCodeTemp = "1000010001" ...
- slot-具名插槽
定义组件:NamedSlot组件 <div class=""> <header> <slot name="header">& ...