- 如果我们在页面中使用定时器, 大概率的思路如下, 在
mounted
中开启定时器并且在beforeDestroy
中销毁定时器.(具体写在哪个生命周期钩子不是这里讨论的重点😀)-
<h1>{{count}}</h1>
-
export default { name: "Student", data() { return { count: 0 }; }, mounted() { this.intervalId = setInterval(() => { this.count++; }, 1000); }, beforeDestroy() { clearInterval(this.intervalId); this.intervalId = null; } };
- 上面的代码导致了两个问题
- 首先, 在
this
上保存定时器id
, 最好的情况是只有生命周期钩子可以访问到它. - 创建定时器的代码和清除定时器的代码互相独立, 很难程序化的清理要建立的所有东西.
- 首先, 在
-
- 可以通过程序化的侦听器解决这个问题
-
export default { name: "Student", data() { return { count: 0 }; }, mounted() { let intervalId = setInterval(() => { this.count++; }, 1000); this.$once('hook:beforeDestroy', () => { console.log('---beforeDestroy---'); clearInterval(intervalId); intervalId = null; }) }, };
- 通过侦听
hook:beforeDestroy
事件, 省略了保存intervalId
同时将注册和清理逻辑放在了一起.
-
- 除此之外呢,
@hook
可以监听子组件的生命周期. 虽然我们都知道子组件和父组件的生命周期存在某种先后关系, 但是了解@hook
也是实现另一种方式- 子组件
-
<h3>Son</h3>
-
export default { mounted() { console.log('Son---mounted'); } }
-
- 父组件
- 使用
@hook:mounted
注册自定义事件. -
<div> <h2>Father</h2> <Son @hook:mounted="childMountHandler"></Son> </div>
-
import Son from './Son.vue' export default { components: { Son }, mounted() { console.log('Father---mounted'); }, methods: { childMountHandler() { console.log('Oops, son mounted'); } } }
- 来看执行顺序
子mounted -> 父hook:mounted -> 父mounted
- 使用
- 子组件