深入解析:Vue 3 父子组件生命周期钩子的执行顺序

1,228 阅读3分钟

在 Vue 3 中,父子组件的生命周期钩子执行顺序是有规律的,下面是对此的详细讲解。


父子组件生命周期钩子执行顺序

1. 组件挂载阶段

当父组件和子组件被创建和挂载时,生命周期钩子的执行顺序如下:

  1. 父组件创建阶段:

    • beforeCreate(父组件)
    • created(父组件)
  2. 子组件创建阶段:

    • beforeCreate(子组件)
    • created(子组件)
  3. 父组件挂载前:

    • beforeMount(父组件)
  4. 子组件挂载阶段:

    • beforeMount(子组件)
    • mounted(子组件)
  5. 父组件挂载阶段:

    • mounted(父组件)

挂载阶段的总结

  • 父组件的创建钩子 (beforeCreatecreated) 总是先于子组件的创建钩子执行。
  • 子组件的挂载钩子 (beforeMountmounted) 总是先于父组件的挂载钩子执行。

完整挂载顺序:

父 beforeCreate → 父 created → 子 beforeCreate → 子 created 
→ 父 beforeMount → 子 beforeMount → 子 mounted → 父 mounted

2. 组件更新阶段

当组件的响应式数据发生变化时,Vue 会触发更新过程。父子组件的更新钩子按以下顺序执行:

  1. 父组件更新前:

    • beforeUpdate(父组件)
  2. 子组件更新阶段:

    • beforeUpdate(子组件)
    • updated(子组件)
  3. 父组件更新后:

    • updated(父组件)

更新阶段的总结

  • 父组件的更新钩子 (beforeUpdate) 先于子组件的更新钩子执行。
  • 子组件的更新完成 (updated) 先于父组件的更新完成钩子执行。

完整更新顺序:

父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated

3. 组件销毁阶段

当父组件或子组件被销毁时,生命周期钩子的执行顺序如下:

  1. 父组件销毁前:

    • beforeUnmount(父组件)
  2. 子组件销毁阶段:

    • beforeUnmount(子组件)
    • unmounted(子组件)
  3. 父组件销毁后:

    • unmounted(父组件)

销毁阶段的总结

  • 父组件的销毁钩子 (beforeUnmount) 先于子组件的销毁钩子执行。
  • 子组件被完全销毁 (unmounted) 先于父组件的销毁完成钩子执行。

完整销毁顺序:

父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted

4. 错误捕获阶段

当子组件中发生未捕获的错误时,可以通过父组件的 errorCaptured 钩子捕获错误。顺序如下:

  1. 子组件发生错误,触发 errorCaptured 钩子:

    • 父组件的 errorCaptured 钩子会被调用。
    • 如果父组件没有捕获错误,错误会继续向祖先组件传播。
  2. 全局错误捕获:

    • 如果没有任何组件捕获错误,全局错误捕获器(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>

运行结果

  1. 挂载阶段
Parent beforeCreate
Parent created
Child beforeCreate
Child created
Parent beforeMount
Child beforeMount
Child mounted
Parent mounted
  1. 更新阶段(父组件或子组件的数据变化时):
Parent beforeUpdate
Child beforeUpdate
Child updated
Parent updated
  1. 销毁阶段
Parent beforeUnmount
Child beforeUnmount
Child unmounted
Parent unmounted