人人都会AI编程

生命周期选项与执行时机

更新时间:2026-07-11

每个 Vue 组件实例从创建到销毁,都会经历一系列固定的步骤,比如初始化数据、编译模板、挂载 DOM、更新 DOM、卸载清理等。Vue 在这些步骤的关键节点提供了生命周期钩子,允许你在特定阶段执行自己的代码。

在选项式 API 中,生命周期钩子是组件选项的一级属性,直接定义为函数:

export default {
  data() { return { user: null } },
  // 生命周期钩子
  created() {
    console.log('组件实例已创建,可以访问 data 和方法')
  },
  mounted() {
    console.log('组件已挂载到 DOM,可以操作真实元素')
  }
}

完整的生命周期流程

Vue 3 的标准生命周期可以分为三个阶段:初始化阶段挂载阶段更新阶段卸载阶段

| 钩子函数(选项式) | 触发时机 | 典型用途 |
|-------------------|----------|----------|
| beforeCreate | 实例刚初始化,数据观测和事件配置之前 | 几乎很少使用,可以通过 setup 替代 |
| created | 实例创建完成,可以访问 data、computed、methods、watch,但尚未挂载到 DOM | 发起异步请求,初始化非响应式数据 |
| beforeMount | 挂载之前,模板已编译,但尚未生成真实 DOM | 很少使用,可以做最后的预处理 |
| mounted | 组件挂载完成,可以访问真实 DOM 元素 | DOM 操作、第三方库初始化(如 ECharts)、依赖 DOM 结构的请求 |
| beforeUpdate | 响应式数据改变,DOM 更新之前 | 在更新前获取旧的 DOM 状态(极少数场景) |
| updated | 数据变更导致 DOM 更新完成后触发 | 避免在此处修改数据,容易造成死循环;可用于需依赖更新后 DOM 的操作 |
| beforeUnmount(Vue 3)<br/>beforeDestroy (Vue 2) | 组件卸载之前,实例依然完全可用 | 清理定时器、取消网络请求、移除事件监听器 |
| unmounted(Vue 3)<br/>destroyed (Vue 2) | 组件卸载完成后,所有子组件已销毁,指令已解绑,事件监听器已移除 | 销毁第三方实例、移除全局副作用 |

执行顺序与父子组件关系

生命周期钩子的执行顺序遵循“从外到内,再从内到外”的规律:

父子组件挂载顺序:

  1. 父组件 beforeCreate
  2. 父组件 created
  3. 父组件 beforeMount
  4. 子组件 beforeCreate
  5. 子组件 created
  6. 子组件 beforeMount
  7. 子组件 mounted
  8. 父组件 mounted

更新阶段是“父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated”。

卸载阶段是“父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted”。

理解这个流程可以避免一些常见的坑点,比如想在父组件 mounted 里获取子组件的 ref,此时子组件已经挂载,所以可以安全访问。

实用经验与常见选择

1. 异步数据请求放哪里?
日常开发中最常用的两个请求位置是 createdmounted

  • 如果你的数据请求不依赖 DOM,放在 created 可以尽早发起请求,减少用户等待时间。
  • 如果需要根据某个 DOM 元素的尺寸或状态来请求,必须放在 mounted(或 watch + nextTick)。

不论哪种方式,请求都是异步的,最终组件渲染完成后数据才回来,所以对首屏展示影响差别不大。结合组合式 API 的 <script setup> 思路,其实直接在顶层使用 async/await 更自然。

2. 不要在 updated 中不加限制地修改数据
因为数据变化会触发 updated,在 updated 里修改数据又会触发新一轮更新,容易造成无限循环。只有当你真的需要在 DOM 更新结果上再做操作时用它,且务必加上防抖或条件判断。

3. 清理副作用是必备习惯
beforeUnmount 中清除定时器、解绑全局事件、取消未完成的请求,可以防止内存泄漏和“组件销毁了仍在偷偷跑代码”的问题。Vue 3 用 beforeUnmount 替代了 Vue 2 的 beforeDestroy,含义更清晰。

与组合式 API 的对应关系

在组合式 API 中,生命周期钩子通过在 setup 中导入的独立函数来使用,名称统一带 on 前缀:

| 选项式 API | 组合式 API(setup 内) |
|-------------------|--------------------------|
| beforeCreate | 无对应钩子,逻辑写于 setup 顶部 |
| created | 同上 |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeUnmount | onBeforeUnmount |
| unmounted | onUnmounted |

此外,还有用于处理 keep-alive 缓存组件的 onActivatedonDeactivated,以及调试用的 onRenderTrackedonRenderTriggered(详见第 10 章相关内容)。掌握这套映射关系,可以让你在两种 API 之间自由切换,设计更加灵活的组件逻辑。