在 Vue 3 中,父子组件的生命周期钩子执行顺序是有规律的,下面是对此的详细讲解。
父子组件生命周期钩子执行顺序
1. 组件挂载阶段
当父组件和子组件被创建和挂载时,生命周期钩子的执行顺序如下:
-
父组件创建阶段:
beforeCreate(父组件)created(父组件)
-
子组件创建阶段:
beforeCreate(子组件)created(子组件)
-
父组件挂载前:
beforeMount(父组件)
-
子组件挂载阶段:
beforeMount(子组件)mounted(子组件)
-
父组件挂载阶段:
mounted(父组件)
挂载阶段的总结
- 父组件的创建钩子 (
beforeCreate和created) 总是先于子组件的创建钩子执行。 - 子组件的挂载钩子 (
beforeMount和mounted) 总是先于父组件的挂载钩子执行。
完整挂载顺序:
父 beforeCreate → 父 created → 子 beforeCreate → 子 created
→ 父 beforeMount → 子 beforeMount → 子 mounted → 父 mounted
2. 组件更新阶段
当组件的响应式数据发生变化时,Vue 会触发更新过程。父子组件的更新钩子按以下顺序执行:
-
父组件更新前:
beforeUpdate(父组件)
-
子组件更新阶段:
beforeUpdate(子组件)updated(子组件)
-
父组件更新后:
updated(父组件)
更新阶段的总结
- 父组件的更新钩子 (
beforeUpdate) 先于子组件的更新钩子执行。 - 子组件的更新完成 (
updated) 先于父组件的更新完成钩子执行。
完整更新顺序:
父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated
3. 组件销毁阶段
当父组件或子组件被销毁时,生命周期钩子的执行顺序如下:
-
父组件销毁前:
beforeUnmount(父组件)
-
子组件销毁阶段:
beforeUnmount(子组件)unmounted(子组件)
-
父组件销毁后:
unmounted(父组件)
销毁阶段的总结
- 父组件的销毁钩子 (
beforeUnmount) 先于子组件的销毁钩子执行。 - 子组件被完全销毁 (
unmounted) 先于父组件的销毁完成钩子执行。
完整销毁顺序:
父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted
4. 错误捕获阶段
当子组件中发生未捕获的错误时,可以通过父组件的 errorCaptured 钩子捕获错误。顺序如下:
-
子组件发生错误,触发
errorCaptured钩子:- 父组件的
errorCaptured钩子会被调用。 - 如果父组件没有捕获错误,错误会继续向祖先组件传播。
- 父组件的
-
全局错误捕获:
- 如果没有任何组件捕获错误,全局错误捕获器(
config.errorHandler)会处理它。
- 如果没有任何组件捕获错误,全局错误捕获器(
完整示例:生命周期顺序演示
下面是一个完整的父子组件生命周期钩子执行顺序的代码示例:
父组件
<template>
<div>
<p>Parent Component</p>
<ChildComponent />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
beforeCreate() {
console.log('Parent beforeCreate');
},
created() {
console.log('Parent created');
},
beforeMount() {
console.log('Parent beforeMount');
},
mounted() {
console.log('Parent mounted');
},
beforeUpdate() {
console.log('Parent beforeUpdate');
},
updated() {
console.log('Parent updated');
},
beforeUnmount() {
console.log('Parent beforeUnmount');
},
unmounted() {
console.log('Parent unmounted');
}
};
</script>
子组件
<template>
<p>Child Component</p>
</template>
<script>
export default {
beforeCreate() {
console.log('Child beforeCreate');
},
created() {
console.log('Child created');
},
beforeMount() {
console.log('Child beforeMount');
},
mounted() {
console.log('Child mounted');
},
beforeUpdate() {
console.log('Child beforeUpdate');
},
updated() {
console.log('Child updated');
},
beforeUnmount() {
console.log('Child beforeUnmount');
},
unmounted() {
console.log('Child unmounted');
}
};
</script>
运行结果
- 挂载阶段:
Parent beforeCreate
Parent created
Child beforeCreate
Child created
Parent beforeMount
Child beforeMount
Child mounted
Parent mounted
- 更新阶段(父组件或子组件的数据变化时):
Parent beforeUpdate
Child beforeUpdate
Child updated
Parent updated
- 销毁阶段:
Parent beforeUnmount
Child beforeUnmount
Child unmounted
Parent unmounted