Vue生命周期
Vue 组件从创建到卸载的关键阶段、常用钩子与使用边界。
#tech / dev / frame
#resource / vue3
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: Vue MOC
- 上位主题: vue3
- 相关概念: vue-next-tick, Vue中的watch和watchEffect
Vue生命周期
一句话定义
生命周期是组件从创建、挂载、更新到卸载的关键时间点,让你在合适的阶段执行初始化、DOM 操作、清理等逻辑。
Composition API 钩子与代码示例
挂载阶段
<script setup>
import { ref, onBeforeMount, onMounted } from 'vue'
const data = ref(null)
// DOM 还未挂载,不能访问 DOM
onBeforeMount(() => {
console.log('组件即将挂载,DOM 尚不可用')
})
// DOM 已挂载,可以操作 DOM、初始化第三方库
onMounted(async () => {
console.log('组件已挂载,DOM 可用')
const res = await fetch('/api/data')
data.value = await res.json()
// 初始化第三方库(如图表、地图)
// echarts.init(document.getElementById('chart'))
})
</script>
onMounted 是最常用的钩子:请求数据、读取 DOM、初始化第三方库都在这里。
更新阶段
<script setup>
import { ref, onBeforeUpdate, onUpdated } from 'vue'
const list = ref([1, 2, 3])
// DOM 即将更新,可以访问更新前的 DOM
onBeforeUpdate(() => {
console.log('DOM 即将更新')
})
// DOM 已更新完成
onUpdated(() => {
console.log('DOM 已更新')
// 注意:不要在这里修改会触发更新的状态,否则会死循环
})
</script>
卸载阶段
<script setup>
import { onBeforeUnmount, onUnmounted, onMounted } from 'vue'
let timer = null
let observer = null
onMounted(() => {
timer = setInterval(() => { /* 轮询逻辑 */ }, 1000)
observer = new IntersectionObserver(() => { /* 观察逻辑 */ })
})
// 组件即将卸载,适合清理副作用
onBeforeUnmount(() => {
clearInterval(timer)
observer.disconnect()
})
// 组件已卸载
onUnmounted(() => {
console.log('组件已完全卸载')
})
</script>
清理工作(定时器、事件监听、WebSocket、Observer)应该放在 onBeforeUnmount 或 onUnmounted 中。
keep-alive 专用钩子
<script setup>
import { onActivated, onDeactivated } from 'vue'
// 被 keep-alive 缓存的组件重新激活时
onActivated(() => {
console.log('组件被激活')
// 重新获取数据或恢复状态
})
// 被 keep-alive 缓存的组件停用时
onDeactivated(() => {
console.log('组件被停用')
// 清理轮询、暂停动画等
})
</script>
Options API 对照
| Composition API | Options API | 时机 |
|---|---|---|
setup() | beforeCreate / created | 组件实例初始化 |
onBeforeMount | beforeMount | DOM 挂载前 |
onMounted | mounted | DOM 挂载后 |
onBeforeUpdate | beforeUpdate | DOM 更新前 |
onUpdated | updated | DOM 更新后 |
onBeforeUnmount | beforeDestroy | 卸载前 |
onUnmounted | destroyed | 卸载后 |
onActivated | activated | keep-alive 激活 |
onDeactivated | deactivated | keep-alive 停用 |
注意:Options API 的 beforeCreate / created 在 Composition API 中对应 setup() 本身,没有独立钩子。
生命周期执行顺序
父 beforeCreate → 父 created → 父 beforeMount
→ 子 beforeCreate → 子 created → 子 beforeMount → 子 mounted
→ 父 mounted
子组件先完成挂载,父组件最后完成。
和 watch / nextTick 的边界
- 生命周期关注”组件现在处在哪个阶段”
- watch 关注”某个状态变化后要做什么”
- vue-next-tick 关注”DOM 更新完成后再做什么”
常见误区
- 所有初始化逻辑都放在
mounted:有些逻辑(如数据预处理)不需要 DOM,可以放在setup()顶层。 - 在
updated里继续改状态:会导致无限更新循环。 - 忘记清理副作用:定时器、事件监听、订阅不清理会造成内存泄漏。
- 在
onMounted里做 SSR 不兼容的操作:onMounted只在客户端执行,SSR 时不会调用。如果需要通用逻辑,放在setup()顶层。 - Options API 的
beforeDestroyvsbeforeUnmount:Vue 3 中统一叫beforeUnmount,beforeDestroy是 Vue 2 的命名。