一、什么是生命周期
Vue 组件就像人的生命周期,有「创建→挂载→更新→销毁」四个核心阶段。每个阶段的前后,Vue 都提供了对应的钩子函数,我们可以把需要在特定时机执行的代码写在里面。
组合式 API 的核心特点
Vue3 组合式 API 中,所有生命周期钩子都以on开头,需要从vue中导入后使用。重要说明:组合式 API 没有beforeCreate和created钩子,setup函数本身的执行时机就等价于这两个钩子,初始化代码直接写在setup里即可。
二、核心生命周期钩子
1. onMounted:组件挂载完成
执行时机
组件第一次渲染到页面,DOM 元素全部生成完成后执行,整个生命周期只执行一次。
核心业务场景
- 发送网络请求,获取页面数据
- 获取 DOM 元素,操作 DOM
- 初始化第三方插件(图表、地图等)
- 绑定全局事件监听
<template> <div> <p ref="pRef">我是页面段落</p> <p>计数:{{ count }}</p> </div> </template> <script setup> import { ref, onMounted } from 'vue' const count = ref(0) const pRef = ref(null) // 用于获取DOM元素 // setup阶段:DOM还未渲染 console.log('setup执行:获取DOM结果', pRef.value) // 打印 null onMounted(() => { // 挂载完成:DOM已渲染,可以正常获取和操作 console.log('onMounted执行:获取DOM结果', pRef.value) console.log('组件挂载完成,可以发请求、初始化插件') }) </script>打开控制台可以看到:setup 里拿不到 DOM,onMounted 里可以正常获取,这是最经典的使用区别。
2. onUpdated:组件更新完成
执行时机
组件的响应式数据发生变化,页面重新渲染完成后执行,数据每次变化都会触发。
核心业务场景
- 数据更新后,操作最新的 DOM 元素
- 监听数据变化后的 DOM 状态
<template> <div> <p>计数:{{ count }}</p> <button @click="count++">计数+1</button> </div> </template> <script setup> import { ref, onUpdated } from 'vue' const count = ref(0) onUpdated(() => { console.log('组件更新完成,最新count值:', count.value) }) </script>点击按钮修改数据,控制台每次都会打印更新后的数值。
3. onUnmounted:组件卸载完成
执行时机
组件被销毁、从页面中移除时执行,整个生命周期只执行一次。
核心业务场景
- 清理定时器、延时器
- 解绑全局事件监听
- 取消未完成的网络请求
- 销毁第三方插件实例
<template> <div> <p>组件运行中...</p> </div> </template> <script setup> import { onUnmounted } from 'vue' // 创建定时器:每秒打印一次 const timer = setInterval(() => { console.log('定时器运行中') }, 1000) // 组件卸载时清理定时器 onUnmounted(() => { clearInterval(timer) console.log('组件已卸载,定时器已清理') }) </script>三、完整生命周期执行顺序
除了三个核心钩子,还有三个前置钩子,对应每个阶段执行前的时机。
| 阶段 | 钩子函数 | 执行时机 | 使用频率 |
|---|---|---|---|
| 初始化 | setup | 组件创建前,DOM 未生成 | 最高(所有代码都在这里) |
| 挂载前 | onBeforeMount | DOM 即将渲染,还未生成 | 低 |
| 挂载完成 | onMounted | DOM 渲染完成 | 极高 |
| 更新前 | onBeforeUpdate | 数据变化,DOM 即将更新 | 低 |
| 更新完成 | onUpdated | 数据变化,DOM 更新完成 | 中 |
| 卸载前 | onBeforeUnmount | 组件即将销毁 | 低 |
| 卸载完成 | onUnmounted | 组件已销毁 | 高 |
<template> <div> <p>计数:{{ count }}</p> <button @click="count++">触发更新</button> </div> </template> <script setup> import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue' const count = ref(0) console.log('1. setup 执行') onBeforeMount(() => { console.log('2. onBeforeMount:挂载前,DOM未生成') }) onMounted(() => { console.log('3. onMounted:挂载完成,DOM已生成') }) onBeforeUpdate(() => { console.log('4. onBeforeUpdate:更新前,DOM即将更新') }) onUpdated(() => { console.log('5. onUpdated:更新完成,DOM已更新') }) onBeforeUnmount(() => { console.log('6. onBeforeUnmount:卸载前,组件即将销毁') }) onUnmounted(() => { console.log('7. onUnmounted:卸载完成,组件已销毁') }) </script>四、本篇核心总结
- 生命周期:组件从创建到销毁的四个阶段,每个阶段对应专属钩子函数
- 三大核心钩子
onMounted:挂载完成,用于发请求、获取 DOM、初始化插件onUpdated:更新完成,用于操作更新后的 DOMonUnmounted:卸载完成,用于清理资源、防止内存泄漏
- 执行顺序:setup → 挂载 → 更新 → 销毁,每个阶段分「前」和「完成」两个钩子