Vue生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
生命周期有哪些
Vue生命周期总共可以分为8个阶段:创建前后, 载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期
生命周期 | 描述 |
---|---|
beforeCreate | 组件实例被创建之初 |
created | 组件实例已经完全创建 |
beforeMount | 组件挂载之前 |
mounted | 组件挂载到实例上去之后 |
beforeUpdate | 组件数据发生变化,更新之前 |
updated | 组件数据更新之后 |
beforeDestroy | 组件实例销毁之前 |
destroyed | 组件实例销毁之后 |
activated | keep-alive 缓存的组件激活时 |
deactivated | keep-alive 缓存的组件停用时调用 |
errorCaptured | 捕获一个来自子孙组件的错误时被调用 |
1. 创建阶段:beforeCreate
→ created
1.1 beforeCreate
钩子
- 触发时机:Vue 实例初始化后,数据观测(
data
响应式处理)和事件机制配置之前。 - 核心特点:
- 无法访问
data
、methods
、computed
等实例属性与方法。 - 无法访问
vm.$el
(DOM 元素尚未初始化)。
- 无法访问
- 典型用途:仅可执行无依赖的初始化操作(如简单的变量声明)。
1.2 created
钩子
- 触发时机:Vue 实例完成数据观测、属性与方法的定义,以及
watch
、event
事件回调的配置后。 - 核心特点:
- 可正常调用
methods
中的方法。 - 可访问和修改
data
数据,修改会触发后续的响应式 DOM 渲染。 - 可通过
computed
计算属性和watch
监听器处理数据。 - 注意:此时
vm.$el
尚未创建,无法操作 DOM。
- 可正常调用
- 典型用途:初始化数据请求(如调用接口获取初始数据)、设置初始数据状态。
2. 挂载阶段:created
→ beforeMount
→ mounted
2.1 created
→ beforeMount
:编译准备
- 核心逻辑:
- 判断实例是否存在
el
选项(挂载目标 DOM):- 若不存在,停止编译,需手动调用
vm.$mount(el)
恢复编译。
- 若不存在,停止编译,需手动调用
- 模板优先级判定:
render
函数 >template
选项 > 挂载目标的outerHTML
。 - 此时
vm.el
仅能获取到未挂载的原始 DOM 节点,未进行模板渲染。
- 判断实例是否存在
2.2 beforeMount
钩子
- 触发时机:模板编译完成后,DOM 挂载到页面之前。
- 核心特点:
- 可获取到
vm.el
(原始 DOM 节点)。 vm.el
已完成 DOM 结构初始化,但未挂载到el
选项指定的目标位置,也未注入响应式数据。
- 可获取到
- 典型用途:对原始 DOM 进行预处理(如添加临时样式、标记)。
2.3 beforeMount
→ mounted
:DOM 挂载
- 核心逻辑:Vue 将编译后的模板(
vm.$el
)渲染为真实 DOM,并替换el
选项指定的原始 DOM 节点,完成 DOM 挂载。
2.4 mounted
钩子
- 触发时机:DOM 完全挂载到页面,且响应式数据已渲染到 DOM 中。
- 核心特点:
- 打印
vm.$el
可看到:原始挂载点及内容已被编译后的新 DOM 替换。 - 可正常操作 DOM(如获取 DOM 尺寸、绑定第三方 DOM 库)。
- 打印
- 典型用途:初始化依赖 DOM 的插件(如图表库、富文本编辑器)、获取 DOM 元素的位置/尺寸。
3. 更新阶段:beforeUpdate
→ updated
3.1 beforeUpdate
钩子
- 触发时机:
data
数据发生变化后,DOM 重新渲染(View 层更新)之前。 - 核心特点:
- 仅当更新的数据被渲染在模板上(通过
el
、template
、render
绑定)时,才会触发。 - 此时 View 层尚未更新,
vm.$el
仍为旧的 DOM 结构。 - 若在该钩子中再次修改
data
数据,不会再次触发更新流程(避免无限循环)。
- 仅当更新的数据被渲染在模板上(通过
- 典型用途:更新前记录旧 DOM 状态(如旧数据、旧 DOM 尺寸)。
3.2 updated
钩子
- 触发时机:
data
数据变化导致 DOM 重新渲染(View 层更新)完成后。 - 核心特点:
- View 层已完全更新,
vm.$el
为最新的 DOM 结构。 - 若在该钩子中再次修改
data
数据,会再次触发更新流程(依次触发beforeUpdate
、updated
),需注意避免无限循环。
- View 层已完全更新,
- 典型用途:更新后基于新 DOM 执行操作(如重新计算 DOM 布局、同步数据到第三方组件)。
4. 销毁阶段:beforeDestroy
→ destroyed
4.1 beforeDestroy
钩子
- 触发时机:Vue 实例被销毁前。
- 核心特点:
- 实例仍处于可用状态,可正常访问
data
、methods
、vm.$el
等属性与方法。 - 尚未执行销毁逻辑,响应式机制、事件监听仍有效。
- 实例仍处于可用状态,可正常访问
- 典型用途:清理实例销毁前的资源(如清除定时器、取消接口请求、解绑自定义事件)。
4.2 destroyed
钩子
- 触发时机:Vue 实例完全销毁后。
- 核心特点:
- 实例与其他实例的连接被切断,所有指令(如
v-model
、v-bind
)和事件监听器(如v-on
)被解绑。 - 实例的
data
、methods
等属性失效,无法再触发响应式更新。 - 注意:仅销毁实例本身,不会主动清除对应的 DOM 元素,需手动处理 DOM 移除。
- 实例与其他实例的连接被切断,所有指令(如
- 典型用途:执行最终的资源释放(如销毁第三方插件实例、清空内存缓存)。
扩展1:数据请求在created和mouted的区别
created
是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成;mounted
是在页面dom节点渲染完毕之后就立刻执行的。触发时机上 created
是比 mounted
要更早的,两者的相同点:都能拿到实例对象的属性和方法。 讨论这个问题本质就是触发的时机,放在 mounted
中的请求有可能导致页面闪动(因为此时页面dom结构已经生成),但如果在页面加载前完成请求,则不会出现此情况。建议对页面内容的改动放在 created
生命周期当中。