目录
当我们使用 Vue 开发项目时,是否想过一个组件从创建到销毁,经历了什么样的过程?Vue 是如何在幕后一步步地帮助我们管理组件的生命周期的?这就是我们今天要聊的重点——Vue 的生命周期。
再简单举个开发中常见的例子,引出生命周期的重要性,例如:
比如你想在组件创建后就立刻发起请求,或者在组件销毁时清理一些监听器和定时器,这时候生命周期函数就能派上用场了。
一、前言:什么是生命周期?
在 Vue 中,生命周期是指一个组件从被创建、渲染、更新到最终被销毁的整个过程。
通俗一点说,每个 Vue 组件都像是一个“有生命的个体”,会经历出生(创建)、成长(挂载)、变化(更新)和死亡(销毁)等阶段。Vue 提供了一系列的“生命周期钩子函数”,让我们在合适的时机执行特定的操作,比如数据初始化、DOM 操作、定时器清理等等。
生命周期:
- 又名:生命周期回调函数、生命周期函数、生命周期钩子。
- 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
- 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
- 生命周期函数中的this指向是vm 或 组件实例对象。
二、为什么要了解生命周期?
开发中,我们常常会遇到这些问题:
-
什么时候发起请求比较合适?
-
何时能访问到 DOM 元素?
-
组件销毁后,事件监听怎么清理?
-
动态更新时如何调试或记录数据变化?
这些都可以通过“生命周期钩子”来精确控制。所以说,理解 Vue 生命周期是开发中不可或缺的一项核心技能。
<div id="root">
<!-- js简写形式 完整应该是{opacity: opacity} -->
<!-- 动态绑定样式 要有 : -->
<h2 :style="{opacity}">欢迎来到{{name}}学习</h2>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: "武汉传媒学院",
opacity: 1
},
methods: {
// 在methods里面不能实现
// change() {
// setInterval(() => {
// this.opacity -= 0.01
// if (this.opacity <= 0) this.opacity = 1
// }, 16);
// }
},
// Vue 完成模板的解析并把初始的真实DOM元素放入页面后,(挂载完毕)调用mounted
mounted() {
setInterval(() => {
this.opacity -= 0.01
if (this.opacity <= 0) this.opacity = 1
}, 16);
},
})
// // 通过外部的定时器实现
// setInterval(() => {
// vm.opacity -= 0.01
// if (vm.opacity <= 0) vm.opacity = 1
// }, 16);
</script>
三、Vue 生命周期阶段总览
我们按照组件“从生到死”的流程来看 Vue 的生命周期,可以分为四个主要阶段:
-
创建阶段:初始化事件 & 生命周期、注入 data 等数据
-
挂载阶段:生成 DOM、挂载组件
-
更新阶段:响应式数据变更引发的重新渲染
-
销毁阶段:组件销毁、解绑事件、清理定时器等
以下是 Vue2 生命周期流程图(官方)建议读者插入:
📌 图示建议:
四、各生命周期钩子函数详解(以 Vue2 为例)
1. beforeCreate
数据观测(data、props 等)和事件配置还未完成,此时无法访问
this.data
或this.methods
。
beforeCreate() {
console.log(this.msg); // undefined
}
2. created
数据已初始化,可以访问
data
和methods
,但还未挂载到 DOM 上。
📌 适合做的事:
-
请求接口获取初始数据
-
设置定时器
-
访问本地缓存
created() {
console.log(this.msg); // Hello Vue
this.getData();
}
3. beforeMount
模板编译完成,但 DOM 还未真正插入页面中,
$el
已生成但未挂载。
使用较少,主要用于调试。
4. mounted
组件 DOM 挂载完成,可以访问并操作真实 DOM。
📌 适合做的事:
-
操作 DOM(如获取元素宽高)
-
发起依赖 DOM 的请求
-
初始化第三方库(如 ECharts)
mounted() {
console.log(this.$refs.box.offsetWidth);
}
5. beforeUpdate
响应式数据更新前调用,此时可以访问当前 DOM 状态。
📌 用于记录更新前的状态,比较变化前后的差异。
6. updated
DOM 更新完成,数据已经变化,页面已重新渲染。
⚠️ 不建议在此操作数据,容易造成死循环。
updated() {
console.log("更新完成!");
}
7. beforeDestroy
实例销毁前调用,此时实例仍然可用。
📌 常用于清理:
-
定时器
-
自定义事件
-
订阅 / 发布模式
beforeDestroy() {
clearInterval(this.timer);
window.removeEventListener('scroll', this.onScroll);
}
8. destroyed
实例已经完全销毁,所有绑定、事件监听、子组件等均被清除。
new Vue({
el:'#root',
// template:`
// <div>
// <h2>当前的n值是:{{n}}</h2>
// <button @click="add">点我n+1</button>
// </div>
// `,
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
watch:{
n(){
console.log('n变了')
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
},
})
五、生命周期的总结
常用的生命周期钩子:
- mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
- beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例:
- 销毁后借助Vue开发者工具看不到任何信息。
- 销毁后自定义事件会失效,但原生DOM事件依然有效。
- 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
生命周期钩子: 当vm即将快被消灭掉的时候,就会调用这个生命周期钩子
beforeDestroy() {
console.log('vm即将驾鹤西游')
clearInterval(this.timer) // 停止的很温柔 只是关闭定时器
},
<div id="root">
<!-- js简写形式 完整应该是{opacity: opacity} -->
<!-- 动态绑定样式 要有 : -->
<h2 :style="{opacity}">欢迎来到{{name}}学习</h2>
<button @click="stop">点我杀死我</button>
</div>
</body>
<script>
const vm = new Vue({
el: '#root',
data: {
name: "武汉传媒学院",
opacity: 1
},
methods: {
stop() {
this.$destroy()
}
},
// Vue 完成模板的解析并把初始的真实DOM元素放入页面后,(挂载完毕)调用mounted
mounted() {
this.timer = setInterval(() => {
this.opacity -= 0.01
if (this.opacity <= 0) this.opacity = 1
}, 16);
},
// 当vm快被消灭的时候 调用这个钩子
// 这就满足不管是上面是否拥有stop函数 就是说明不管 你是自杀还是他杀 都会走到这个程序,
// 那么我就帮你关掉这个定时器,否则如果这个关闭定时器写在stop函数里面 但是vm结束的时候
// 并没有通过调用vm函数而直接死亡
// 这里就相当于是善后工作 只要张三被解决了就会走到这一步
// 我并不知道 我订阅的10条公众号 和 20条消息到底是要点击按钮进行关闭 还是 怎么进行关闭
// 那么我都可以把关闭这种消息的善后工作都放到这一步来一起进行关闭即可
beforeDestroy() {
console.log('vm即将驾鹤西游')
clearInterval(this.timer) // 停止的很温柔 只是关闭定时器
},
})