Skip to content

Vue生命周期

每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。

生命周期有哪些

Vue生命周期总共可以分为8个阶段:创建前后, 载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期

生命周期描述
beforeCreate组件实例被创建之初
created组件实例已经完全创建
beforeMount组件挂载之前
mounted组件挂载到实例上去之后
beforeUpdate组件数据发生变化,更新之前
updated组件数据更新之后
beforeDestroy组件实例销毁之前
destroyed组件实例销毁之后
activatedkeep-alive 缓存的组件激活时
deactivatedkeep-alive 缓存的组件停用时调用
errorCaptured捕获一个来自子孙组件的错误时被调用

1. 创建阶段:beforeCreatecreated

1.1 beforeCreate 钩子

  • 触发时机:Vue 实例初始化后,数据观测(data 响应式处理)和事件机制配置之前。
  • 核心特点
    • 无法访问 datamethodscomputed 等实例属性与方法。
    • 无法访问 vm.$el(DOM 元素尚未初始化)。
  • 典型用途:仅可执行无依赖的初始化操作(如简单的变量声明)。

1.2 created 钩子

  • 触发时机:Vue 实例完成数据观测、属性与方法的定义,以及 watchevent 事件回调的配置后。
  • 核心特点
    • 可正常调用 methods 中的方法。
    • 可访问和修改 data 数据,修改会触发后续的响应式 DOM 渲染。
    • 可通过 computed 计算属性和 watch 监听器处理数据。
    • 注意:此时 vm.$el 尚未创建,无法操作 DOM。
  • 典型用途:初始化数据请求(如调用接口获取初始数据)、设置初始数据状态。

2. 挂载阶段:createdbeforeMountmounted

2.1 createdbeforeMount:编译准备

  • 核心逻辑
    1. 判断实例是否存在 el 选项(挂载目标 DOM):
      • 若不存在,停止编译,需手动调用 vm.$mount(el) 恢复编译。
    2. 模板优先级判定:render 函数 > template 选项 > 挂载目标的 outerHTML
    3. 此时 vm.el 仅能获取到未挂载的原始 DOM 节点,未进行模板渲染。

2.2 beforeMount 钩子

  • 触发时机:模板编译完成后,DOM 挂载到页面之前。
  • 核心特点
    • 可获取到 vm.el(原始 DOM 节点)。
    • vm.el 已完成 DOM 结构初始化,但未挂载到 el 选项指定的目标位置,也未注入响应式数据。
  • 典型用途:对原始 DOM 进行预处理(如添加临时样式、标记)。

2.3 beforeMountmounted:DOM 挂载

  • 核心逻辑:Vue 将编译后的模板(vm.$el)渲染为真实 DOM,并替换 el 选项指定的原始 DOM 节点,完成 DOM 挂载。

2.4 mounted 钩子

  • 触发时机:DOM 完全挂载到页面,且响应式数据已渲染到 DOM 中。
  • 核心特点
    • 打印 vm.$el 可看到:原始挂载点及内容已被编译后的新 DOM 替换。
    • 可正常操作 DOM(如获取 DOM 尺寸、绑定第三方 DOM 库)。
  • 典型用途:初始化依赖 DOM 的插件(如图表库、富文本编辑器)、获取 DOM 元素的位置/尺寸。

3. 更新阶段:beforeUpdateupdated

3.1 beforeUpdate 钩子

  • 触发时机data 数据发生变化后,DOM 重新渲染(View 层更新)之前。
  • 核心特点
    • 仅当更新的数据被渲染在模板上(通过 eltemplaterender 绑定)时,才会触发。
    • 此时 View 层尚未更新,vm.$el 仍为旧的 DOM 结构。
    • 若在该钩子中再次修改 data 数据,不会再次触发更新流程(避免无限循环)。
  • 典型用途:更新前记录旧 DOM 状态(如旧数据、旧 DOM 尺寸)。

3.2 updated 钩子

  • 触发时机data 数据变化导致 DOM 重新渲染(View 层更新)完成后。
  • 核心特点
    • View 层已完全更新,vm.$el 为最新的 DOM 结构。
    • 若在该钩子中再次修改 data 数据,会再次触发更新流程(依次触发 beforeUpdateupdated),需注意避免无限循环。
  • 典型用途:更新后基于新 DOM 执行操作(如重新计算 DOM 布局、同步数据到第三方组件)。

4. 销毁阶段:beforeDestroydestroyed

4.1 beforeDestroy 钩子

  • 触发时机:Vue 实例被销毁前。
  • 核心特点
    • 实例仍处于可用状态,可正常访问 datamethodsvm.$el 等属性与方法。
    • 尚未执行销毁逻辑,响应式机制、事件监听仍有效。
  • 典型用途:清理实例销毁前的资源(如清除定时器、取消接口请求、解绑自定义事件)。

4.2 destroyed 钩子

  • 触发时机:Vue 实例完全销毁后。
  • 核心特点
    • 实例与其他实例的连接被切断,所有指令(如 v-modelv-bind)和事件监听器(如 v-on)被解绑。
    • 实例的 datamethods 等属性失效,无法再触发响应式更新。
    • 注意:仅销毁实例本身,不会主动清除对应的 DOM 元素,需手动处理 DOM 移除。
  • 典型用途:执行最终的资源释放(如销毁第三方插件实例、清空内存缓存)。

扩展1:数据请求在created和mouted的区别

created 是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成;mounted 是在页面dom节点渲染完毕之后就立刻执行的。触发时机上 created 是比 mounted 要更早的,两者的相同点:都能拿到实例对象的属性和方法。 讨论这个问题本质就是触发的时机,放在 mounted 中的请求有可能导致页面闪动(因为此时页面dom结构已经生成),但如果在页面加载前完成请求,则不会出现此情况。建议对页面内容的改动放在 created 生命周期当中。

尘埃虽微,积之成集;问题虽小,记之为鉴。 雾中低语,心之所向;思绪飘渺,皆可成章。