Vue 3 生命周期钩子完全指南
本文档从零开始讲解 Vue 3 的生命周期钩子:组件从创建到销毁会经历哪些阶段、每个阶段对应哪些钩子、在钩子里能做什么和不能做什么、选项式 API 与组合式 API 的写法对比,以及常见用法示例,适合新手系统学习。
一、什么是“生命周期”?
1.1 生活中的类比
一个组件就像一个人:出生(创建)→ 出现在世界上(挂载到页面)→ 成长变化(数据更新、视图更新)→ 离开(从页面移除、销毁)。
Vue 在这些关键时间点提供了“钩子”(函数),你可以在里面写自己的代码,例如:组件挂载好后去请求接口、即将销毁前清除定时器。
1.2 为什么需要钩子?
- created / setup 执行完:数据、计算属性已经有了,但还没有 DOM,不能操作 document.querySelector。
- mounted:组件已经挂载到 DOM,可以安全地操作自己的 DOM、发请求、加事件监听。
- unmounted:组件即将被移除,应在这里移除监听、清定时器,避免内存泄漏。
所以“生命周期”就是组件的几个阶段,“钩子”就是你在每个阶段可以插入的代码。
二、生命周期有哪些阶段?(总览)
Vue 3 组件的生命周期大致分为四段:
- 创建(Creation):组件实例被创建,数据、计算属性等初始化。
- 挂载(Mounting):把组件渲染出来的 DOM 插入到页面上。
- 更新(Updating):响应式数据变化,组件重新渲染。
- 卸载(Unmounting):组件从页面上移除并销毁。
每一段都有“之前”和“之后”的钩子(部分阶段只有“之后”)。下面按顺序说明每个钩子在什么时候执行、适合做什么。
三、选项式 API 的生命周期钩子
在 export default { } 里可以写这些选项(函数):
| 钩子名 | 执行时机 |
|---|---|
| beforeCreate | 组件实例刚创建,data、methods 还未初始化 |
| created | data、methods 等已初始化,但 DOM 还未生成 |
| beforeMount | 即将把组件渲染成 DOM 并插入页面之前 |
| mounted | DOM 已插入页面,可以操作自己的 DOM、发请求 |
| beforeUpdate | 数据变化后,虚拟 DOM 即将重新渲染、打补丁之前 |
| updated | DOM 已更新完成 |
| beforeUnmount | 组件即将被销毁、从页面移除之前 |
| unmounted | 组件已销毁、已从页面移除,最后做清理 |
3.1 beforeCreate
- 时机:组件实例刚被创建,data、methods、computed 都还没有。
- 用途:极少在这里写逻辑,因为拿不到数据。
- 示例:一般不用。
3.2 created
- 时机:data、methods、computed 已经初始化好,可以访问 this.xxx;但还没有 DOM(没有挂载到页面上)。
- 用途:发请求、初始化一些不依赖 DOM 的数据。
- 注意:不能在这里用 document.querySelector 或 this.$refs 拿 DOM,DOM 还不存在。
export default {
data() {
return { list: [] }
},
created() {
console.log('data 已有,DOM 还没有')
this.fetchList()
},
methods: {
async fetchList() {
const res = await fetch('/api/list')
this.list = await res.json()
}
}
}
3.3 beforeMount
- 时机:即将把组件的模板编译成 DOM 并插入到页面之前。
- 用途:很少用;需要“最后一刻改数据再渲染”时才会用。
- 示例:一般不用。
3.4 mounted(最常用之一)
- 时机:组件的 DOM 已经插入到页面,可以认为“组件已经显示在屏幕上了”。
- 用途:
- 操作自己的 DOM(如 focus、测量宽高)。
- 发请求(若 created 没发)。
- 添加需要手动移除的监听(如 window、document 事件),并在 unmounted 里移除。
- 注意:子组件的 mounted 会先于父组件的 mounted 执行(子先挂载完,父再挂载完)。