Vue 3 生命周期钩子详解与案例代码
Vue 3 引入了 组合式 API(Composition API),使得生命周期钩子的使用更加灵活和模块化。以下将详细介绍 Vue 3 中的生命周期钩子,包括所有钩子函数的使用方法,并提供一个详细的案例代码,附带详细注释,帮助 Vue 3 初学者快速上手。
一、Vue 3 生命周期钩子概述
Vue 组件的生命周期分为多个阶段,每个阶段都有对应的生命周期钩子函数,允许开发者在特定的时间点执行代码。以下是 Vue 3 中的主要生命周期钩子:
1. 创建阶段(Creation)
beforeCreate
: 组件实例初始化之后,数据观测和事件配置之前调用。此时无法访问data
、computed
、methods
等。created
: 组件实例创建完成,数据观测、事件配置、响应式属性都已完成,但尚未挂载到 DOM。可以访问data
、computed
、methods
等。
2. 挂载阶段(Mounting)
beforeMount
: 在挂载开始之前被调用:相关的render
函数首次被调用。mounted
: 组件被挂载到 DOM 上后调用。可以访问 DOM 元素。
3. 更新阶段(Updating)
beforeUpdate
: 数据更新导致虚拟 DOM 重新渲染和打补丁之前被调用。updated
: 组件 DOM 更新完成之后调用。可以访问更新后的 DOM。
4. 卸载阶段(Unmounting)
beforeUnmount
: 组件实例被卸载之前调用。unmounted
: 组件实例被卸载后调用。可以执行清理操作,如定时器、事件监听器等。
5. 其他钩子
activated
和deactivated
: 用于<keep-alive>
组件包裹的动态组件,激活和停用时调用。errorCaptured
: 当捕获一个来自子孙组件的错误时被调用。
二、生命周期钩子使用示例
以下是一个使用 Vue 3 组合式 API 的示例,展示了各个生命周期钩子的使用方式,并附有详细注释。
1. 项目结构
假设项目结构如下:
src/
├── components/
│ └── LifecycleComponent.vue
└── App.vue
2. LifecycleComponent.vue
<template>
<div>
<h2>{{ title }}</h2>
<p>当前计数器值: {{ count }}</p>
<button @click="increment">增加</button>
<button @click="destroyComponent">销毁组件</button>
</div>
</template>
<script>
import { ref, onBeforeCreate, onCreated, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';
export default {
name: 'LifecycleComponent',
setup() {
// 响应式数据
const count = ref(0);
const title = ref('Vue 3 生命周期钩子示例');
// 计数器增加方法
const increment = () => {
count.value++;
};
// 销毁组件方法
const destroyComponent = () => {
// 通过设置父组件的某个条件来销毁当前组件
// 这里为了演示,假设有一个父组件的变量控制显示
// 但为了简化,直接使用 unmounted 钩子
// 实际使用中,可以通过 v-if 或其他方式控制
};
// 生命周期钩子
onBeforeCreate(() => {
console.log('beforeCreate: 组件实例初始化之后,数据观测和事件配置之前');
// 此时无法访问 count 和 title
});
onCreated(() => {
console.log('created: 组件实例创建完成,数据观测、事件配置已完成');
console.log('count:', count.value); // 可以访问 count
console.log('title:', title.value); // 可以访问 title
});
onBeforeMount(() => {
console.log('beforeMount: 挂载开始之前被调用');
});
onMounted(() => {
console.log('mounted: 组件被挂载到 DOM 上后调用');
console.log('DOM:', document.querySelector('.lifecycle-component'));
});
onBeforeUpdate(() => {
console.log('beforeUpdate: 数据更新导致虚拟 DOM 重新渲染之前');
});
onUpdated(() => {
console.log('updated: 组件 DOM 更新完成之后');
console.log('更新后的 DOM:', document.querySelector('.lifecycle-component'));
});
onBeforeUnmount(() => {
console.log('beforeUnmount: 组件实例被卸载之前');
});
onUnmounted(() => {
console.log('unmounted: 组件实例被卸载后');
// 执行清理操作,如定时器、事件监听器等
});
return {
count,
title,
increment,
destroyComponent
};
}
};
</script>
<style scoped>
.lifecycle-component {
border: 1px solid #ccc;
padding: 16px;
margin: 16px 0;
}
</style>
3. App.vue
为了演示组件的挂载和卸载,我们在 App.vue
中添加一个按钮来切换 LifecycleComponent
的显示。
<template>
<div id="app">
<h1>Vue 3 生命周期钩子示例</h1>
<button @click="showComponent = !showComponent">
{{ showComponent ? '隐藏' : '显示' }} LifecycleComponent
</button>
<div v-if="showComponent" class="lifecycle-component">
<LifecycleComponent />
</div>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import LifecycleComponent from './components/LifecycleComponent.vue';
export default {
name: 'App',
components: {
LifecycleComponent
},
setup() {
const showComponent = ref(true);
onMounted(() => {
console.log('App mounted');
});
return {
showComponent
};
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
margin-top: 60px;
}
</style>
4. 解释与运行效果
生命周期钩子调用顺序
创建阶段
beforeCreate
: 组件实例初始化后,数据观测和事件配置之前。created
: 组件实例创建完成,数据观测、事件配置已完成。
挂载阶段
beforeMount
: 挂载开始之前。mounted
: 组件被挂载到 DOM 上后。
更新阶段
- 当点击“增加”按钮时,
count
变化,触发更新:beforeUpdate
: 数据更新导致虚拟 DOM 重新渲染之前。updated
: 组件 DOM 更新完成之后。
- 当点击“增加”按钮时,
卸载阶段
- 当点击“销毁组件”按钮时,组件被卸载:
beforeUnmount
: 组件实例被卸载之前。unmounted
: 组件实例被卸载后。
- 当点击“销毁组件”按钮时,组件被卸载:
控制台输出示例
beforeCreate: 组件实例初始化之后,数据观测和事件配置之前
created: 组件实例创建完成,数据观测、事件配置已完成
count: 0
title: Vue 3 生命周期钩子示例
beforeMount: 挂载开始之前被调用
mounted: 组件被挂载到 DOM 上后调用
DOM: <div class="lifecycle-component">...</div>
当点击“增加”按钮时,控制台输出:
beforeUpdate: 数据更新导致虚拟 DOM 重新渲染之前
updated: 组件 DOM 更新完成之后
更新后的 DOM: <div class="lifecycle-component">...</div>
当点击“销毁组件”按钮时,控制台输出:
beforeUnmount: 组件实例被卸载之前
unmounted: 组件实例被卸载后
三、总结
通过上述示例,可以清晰地看到 Vue 3 中生命周期钩子的调用顺序及其作用。以下是一些关键点:
- 组合式 API 的优势: 使用
setup
函数和组合式 API 可以更灵活地组织代码,尤其适合大型项目。 - 生命周期钩子的使用: 各个生命周期钩子允许开发者在组件的不同阶段执行特定的逻辑,如数据初始化、DOM 操作、清理资源等。
- 响应式数据: 在
setup
中定义的ref
和reactive
数据在生命周期钩子中都是可访问的,提供了更强大的数据管理能力。
希望这份详细的指南能够帮助 Vue 3 初学者更好地理解和使用生命周期钩子。如果有更多问题,欢迎继续交流!