组件生命周期是 Vue 实例从创建到销毁的完整过程,它通过一系列预定义的钩子函数(lifecycle hooks)允许开发者在特定阶段插入自定义逻辑。理解生命周期有助于开发者精确控制组件的初始化、数据交互、DOM 操作及资源清理,是构建可靠 Vue 应用的基础。
Vue 3 的组件生命周期可分为四个主要阶段:创建阶段(Creation)、挂载阶段(Mounting)、更新阶段(Updating)和卸载阶段(Unmounting),每个阶段对应特定的钩子函数与核心操作。以下为各阶段的详细说明:
创建阶段:组件实例初始化阶段,主要完成数据观测(data observation)、事件绑定等基础设置。此阶段 DOM 尚未生成,无法进行 DOM 操作。
挂载阶段:组件实例与 DOM 关联的阶段,完成模板编译、DOM 插入等操作,是进行 DOM 相关初始化的关键阶段。
更新阶段:组件响应数据变化并重新渲染的阶段,当 data 或 props 发生变化时触发。
卸载阶段:组件从 DOM 中移除并销毁的阶段,主要完成资源清理,避免内存泄漏。
Vue 2 与 Vue 3 生命周期钩子名称对比
beforeCreate(不变)、created(不变) beforeMount(不变)、mounted(不变) beforeUpdate(不变)、updated(不变) beforeDestroy → beforeUnmount、destroyed → unmounted activated/deactivated(keep-alive 相关)在 Vue 3 中保留,组合式 API 中需通过 onActivated/onDeactivated 使用。在实际开发中,mounted(初始化操作)和 beforeUnmount(资源清理)是最常用的钩子函数。以下通过“数据加载与清理”案例,分别展示 Options API 与 Composition API 两种风格的实现方式,并说明钩子的执行时机与应用场景。
Options API 通过配置对象的属性定义生命周期钩子,适合逻辑简单的组件。以下案例实现一个“数据统计卡片”组件:在组件挂载后请求数据并渲染,同时启动定时器更新统计数据,组件卸载前清理定时器。
<template>
<div class="stats-card">
<h3>{{ title }}</h3>
<p>当前在线人数:{{ onlineUsers }}</p>
<p>今日访问量:{{ todayViews }}</p>
</div>
</template>
<script>
export default {
name: 'StatsCard',
data() {
return {
title: '实时数据统计',
onlineUsers: 0,
todayViews: 0,
updateTimer: null // 存储定时器 ID,用于清理
}
},
// 组件挂载后执行,适合初始化操作(DOM 已生成)
mounted() {
// 1. 初始化请求:获取初始数据
this.fetchStatsData()
// 2. 启动定时器:每 30 秒更新一次数据
this.updateTimer = setInterval(() => {
this.fetchStatsData()
}, 30000)
console.log('组件已挂载,DOM 可访问')
},
// 组件卸载前执行,适合资源清理
beforeUnmount() {
// 清理定时器,避免组件销毁后继续执行
clearInterval(this.updateTimer)
console.log('组件即将卸载,定时器已清理')
},
methods: {
async fetchStatsData() {
try {
const response = await fetch('/api/stats')
const data = await response.json()
this.onlineUsers = data.onlineUsers
this.todayViews = data.todayViews
} catch (error) {
console.error('数据请求失败:', error)
}
}
}
}
</script>
代码说明:
mounted 钩子中执行两项关键操作:调用 fetchStatsData 发起初始数据请求,通过 setInterval 启动定时更新。此时组件已挂载到 DOM,可安全进行数据渲染。 beforeUnmount 钩子中通过 clearInterval 清理定时器,防止组件卸载后定时器继续运行导致内存泄漏。 Composition API 通过 setup 函数(或 <script setup> 语法糖)组织逻辑,允许将相关代码(如数据请求与清理)聚合在一起,提升代码可维护性。以下为相同功能的 Composition API 实现:
<template>
<div class="stats-card">
<h3>{{ title }}</h3>
<p>当前在线人数:{{ onlineUsers }}</p>
<p>今日访问量:{{ todayViews }}</p>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
// 定义响应式数据
const title = ref('实时数据统计')
const onlineUsers = ref(0)
const todayViews = ref(0)
let updateTimer = null // 非响应式变量,无需用 ref 包裹
// 数据请求函数
const fetchStatsData = async () => {
try {
const response = await fetch('/api/stats')
const data = await response.json()
onlineUsers.value = data.onlineUsers
todayViews.value = data.todayViews
} catch (error) {
console.error('数据请求失败:', error)
}
}
// 挂载阶段钩子:组件挂载后执行
onMounted(() => {
fetchStatsData() // 初始数据请求
updateTimer = setInterval(fetchStatsData, 30000) // 启动定时器
console.log('组件已挂载,DOM 可访问')
})
// 卸载阶段钩子:组件卸载前执行
onBeforeUnmount(() => {
clearInterval(updateTimer) // 清理定时器
console.log('组件即将卸载,定时器已清理')
})
</script>
代码说明:
import 引入 onMounted、onBeforeUnmount 等生命周期钩子函数,在 setup 中直接调用并传入回调函数。 fetchStatsData)、定时器创建与清理逻辑集中在同一代码块,形成“功能内聚”的逻辑单元,避免 Options API 中“配置项分散”的问题。 ref 创建,非响应式变量(如 updateTimer)直接声明,简化状态管理。组合式 API 对生命周期钩子进行了函数式封装,统一以 onXxx 命名(如 onMounted、onUpdated),需从 vue 导入后在 setup 函数或 <script setup> 中使用。这种设计允许将分散在不同生命周期的相关逻辑聚合,尤其适合复杂组件的代码组织。
语法形式:组合式 API 钩子为高阶函数,接收一个回调函数作为参数,回调函数内的逻辑将在对应生命周期阶段执行。例如:
import { onMounted } from 'vue'
setup() {
onMounted(() => {
console.log('组件挂载完成')
// DOM 操作或数据请求逻辑
})
}
逻辑聚合:相比 Options API 中钩子函数需分散定义,组合式 API 可将同一功能的“初始化-清理”逻辑放在一起。例如,数据请求与定时器清理可紧邻编写,增强代码可读性与可维护性。
与 setup 的关系:setup 函数在 beforeCreate 和 created 钩子之间执行,因此无需单独使用这两个钩子,直接在 setup 中编写初始化逻辑即可。
以下通过“用户列表组件”案例,完整展示组合式 API 生命周期钩子的使用流程,涵盖数据加载、渲染、更新与清理的全流程。
<template>
<div class="user-list">
<h2>用户列表</h2>
<div v-if="loading" class="loading">加载中...</div>
<div v-else-if="error" class="error">{{ error }}</div>
<ul v-else>
<li v-for="user in users" :key="user.id">
{{ user.name }} ({{ user.email }})
</li>
</ul>
<button @click="refreshUsers">刷新列表</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, onUpdated } from 'vue'
// 状态管理
const users = ref([])
const loading = ref(false)
const error = ref(null)
let pollingInterval = null // 轮询定时器
// 加载用户数据
const loadUsers = async () => {
loading.value = true
error.value = null
try {
const response = await fetch('/api/users')
if (!response.ok) throw new Error('请求失败')
users.value = await response.json()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
// 挂载阶段:初始化数据与轮询
onMounted(() => {
loadUsers() // 初始加载
// 启动轮询:每 60 秒自动刷新数据
pollingInterval = setInterval(loadUsers, 60000)
console.log('用户列表组件挂载完成')
})
// 更新阶段:监控数据变化
onUpdated(() => {
console.log(`用户列表更新,当前用户数:${users.value.length}`)
})
// 卸载阶段:清理资源
onBeforeUnmount(() => {
clearInterval(pollingInterval) // 停止轮询
console.log('用户列表组件卸载,轮询已停止')
})
// 手动刷新方法
const refreshUsers = () => {
loadUsers()
}
</script>
案例解析:
ref 创建响应式状态 users(用户列表)、loading(加载状态)、error(错误信息),以及非响应式变量 pollingInterval(轮询定时器 ID)。 loadUsers 函数封装数据请求逻辑,通过 fetch 获取用户数据,同时管理 loading 和 error 状态。 onMounted:组件挂载后执行初始数据加载,并启动每 60 秒一次的自动刷新轮询。 onUpdated:用户列表数据更新后触发,可用于日志记录或性能监控。 onBeforeUnmount:组件卸载前清除轮询定时器,防止内存泄漏。refreshUsers 方法供按钮调用,支持手动刷新数据,体现生命周期钩子与用户操作的协同。| 特性 | Options API | 组合式 API |
|---|---|---|
| 定义方式 | 配置项形式(如 mounted: function() {}) |
函数调用形式(如 onMounted(() => {})) |
| 逻辑组织 | 按生命周期分散在不同配置项 | 按功能聚合,相关逻辑可紧邻编写 |
| 灵活性 | 固定配置结构,扩展受限 | 可在任意函数中调用,支持逻辑复用 |
| 适用场景 | 简单组件,逻辑清晰且分散度低 | 复杂组件,需聚合多生命周期相关逻辑 |
组合式 API 钩子使用要点
onXxx 钩子需在 setup 执行期间注册,确保回调函数能正确绑定组件实例。 onMounted(() => console.log('挂载回调 1'))
onMounted(() => console.log('挂载回调 2')) // 依次执行
onUpdated 中修改 ref 数据)。Vue 3 生命周期钩子是组件生命周期管理的核心工具,通过创建、挂载、更新、卸载四个阶段的钩子函数,实现对组件行为的精确控制。组合式 API 以函数式方式重构了生命周期钩子,通过 onMounted、onBeforeUnmount 等函数,将相关逻辑聚合,解决了 Options API 中代码分散的问题,尤其适合复杂组件的开发。
在实际开发中,需根据组件复杂度选择 API 风格:简单组件可使用 Options API 保持简洁,复杂组件推荐组合式 API 提升逻辑组织性。无论采用哪种方式,均需重视资源清理(如定时器、事件监听),避免内存泄漏,确保应用性能与稳定性。
通过合理运用生命周期钩子,开发者可实现组件从初始化到销毁的全流程可控,为构建健壮、高效的 Vue 应用奠定基础。