生命周期钩子函数
浏览 746
课文
这节课我们来详细学习 Vue 实例的生命周期钩子。
生命周期钩子
Vue 实例从被创建出来,就开始经历它的生命周期。在生命周期的过程中,它会提供一些功能,这些功能会在生命周期的每个过渡步骤中执行,以便我们在这些阶段执行某些任务。我们可以把生命周期想象成一个管道,这个管道上面有很多钩子,把我们要做的某些任务钩住。所以这些函数被称为“生命周期钩子(Hook)”。
Vue 总共有 8 个生命周期钩子。每个生命周期阶段都有 2 个钩子,总结如下:
- create hook
- beforeCreate
- created
- mount hook
- beforeMount
- mounted
- update hook
- beforeUpdate
- updated
- before hook
- beforeDestroy
- destroyed
接下来我们将分别学习每个钩子。
创建 Hook
beforeCreate
beforeCreate 会在在组件初始化时运行。这时 data 和 methods 都没有被挂载到 Vue 实例上。
new Vue({
el: '#app',
data: {
name: '张三'
},
methods: {},
beforeCreate() {
console.log(this.name);
}
})
在上面的示例中,当 beforeCreate 钩子运行时,会在控制台输出 undefined,因为 data 尚未被处理。
created
created 允许访问通过 created 钩子激活的反应数据和事件。这时 template 和虚拟 DOM 还没有被渲染和创建。
<!DOCTYPE html>
<html>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<body>
<div id="app"></div>
<script>
new Vue({
el: '#app',
data: {
name: '张三'
},
template: '<div>my name is {{ name }}</div>',
created() {
const el = document.getElementById('app')
console.log(el.innerHTML)
}
})
</script>
</body>
</html>
此时打印的内容是空白的,说明此时 template 并没有被渲染到页面中。
挂载 hook
beforeMount
beforeMount 发生在初始渲染发生之后,需要呈现的内容都已经被编译完成。
new Vue({
el: '#app',
beforeMount() {
console.log('模板已完成渲染')
console.log('虚拟 DOM 尚未创建:', this.$el)
}
})
其中 this.$el 是虚拟 DOM 所对应的真实 DOM 的包装对象,此时还没有这个对象,所以是 undefined。
mounted
在 mounted 钩子中,可以完全访问反应式组件、模板和呈现的 DOM(通过this.$el)。
可以在 mounted 中来修改DOM,尤其是在和其它 UI 框架/库集成的时候格外有用。
new Vue({
el: '#app',
mounted() {
console.log('虚拟 DOM 已创建:', Object.keys(this.$el.__vue__).join('\n'))
}
})
在上面的示例中,我们打印了 this.$el.vue 上面的所有属性。
更新 hook
beforeUpdate
beforeUpdate 钩子在组件上的响应式数据(data)发生变化后运行,这时开始更新。但此时是在修补 DOM 和重新渲染 DOM 之前进行的。
我们可以在 beforeUpdate 中获取组件上的任何响应数据的最新状态。
new Vue({
el: '#app',
data: {
name: '张三'
},
template: '<div>my name is {{ name }}</div>',
beforeCreate() {
setTimeout(() => this.name='李四', 1000)
},
beforeUpdate() {
console.log(this.name);
}
})
updated
updated 钩子在组件上的数据更新,并且 DOM 重新渲染后运行。
我们可以在属性更新后,在 updated 中根据需要来访问真实的 DOM。
new Vue({
el: '#app',
data: {
name: '张三'
},
template: '<div id="name">my name is {{ name }}</div>',
beforeCreate() {
setTimeout(() => this.name='李四', 1000)
},
beforeUpdate() {
console.log(this.name);
},
updated() {
console.log(document.getElementById('name').innerHTML);
}
})
销毁 hook
beforeDestroy
beforeDestroy 在组件销毁前执行。这时的组件仍将完全存在并正常运行。
beforeDestroy 非常适合清理事件和一些副作用。
const vm = new Vue({
el: '#app',
beforeDestroy() {
console.log('我马上就要被销毁了!!!');
}
})
vm.$destroy()
destroyed
组件销毁后,会进入 destroyed 钩子,这时组件上几乎没有任何东西。附着在它上面的一切都被销毁了。
通常我们会在 destroyed 中做一些延迟执行的任务,比如通知服务器,组件已被销毁。
new Vue({
el: '#app',
destroyed() {
console.log('我已经被销毁了!');
}
})
**恭喜!**🎉🎊 现在您已经掌握了 Vue.js 所有的生命周期钩子。
下面是调用了 Vue 实例所有生命周期钩子的可执行示例。
我已经在每一个生命周期 hook 中通过控制台打印了消息,这样以便你查看钩子的执行顺序。
<!DOCTYPE html>
<html>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<body>
<div id="app"></div>
<script>
let vm = new Vue({
el: "#app",
data: {
date: Date()
},
template: `<div>
<h1>这是一个用于观察 Vue.js 生命周期的示例</h1>
<p>请打开浏览器的控制台观察它们是以什么顺序来执行的。</p>
<h3>每隔 1 秒会更新时间,所以每隔一秒会执行一次 update hooks。</h3>
<h3>Vue.js 实例将会在 3 秒后自动销毁,所以 destroy hooks 将会在 3 秒后被执行。</h3>
<h3>当前时间:{{ this.date }}</h3>
</div>
`,
beforeCreate() {
console.log("beforeCreate:事件和生命周期已初始化");
},
created() {
console.log("created:Vue 实例已创建");
},
beforeMount() {
console.log("beforeMount:$el 尚未被创建");
},
mounted() {
console.log("mounted:$el 已创建,DOM 已被替换");
},
beforeUpdate() {
console.log("beforeUpdate:虚拟 DOM 尚未被重新渲染和更新");
},
updated() {
console.log("updated:虚拟 DOM 已经被重新渲染和更新");
},
beforeDestroy() {
console.log(
"beforeDestroy:开始销毁,数据响应式和事件监听尚未被移除"
);
},
destroyed() {
console.log("destroyed:销毁完毕,数据响应式和事件监听已被移除");
},
});
const timer = setInterval(function () {
vm.date = new Date()
}, 1000);
setTimeout(function () {
vm.$destroy();
clearInterval(timer)
}, 3000);
</script>
</body>
</html>
评论
暂无评论