【vue】vue中父子组件的生命周期
·
Vue 父子组件生命周期执行顺序(Vue2 + Vue3 全解析)
Vue 父子组件的生命周期执行遵循**「父先初始化、子先完成挂载;父先触发销毁、子先完成销毁」** 的核心规则,不同阶段(挂载/更新/销毁)的执行顺序有明确规律,且 Vue2(选项式 API)和 Vue3(选项式/组合式 API)的核心逻辑一致,仅钩子名称略有差异。
一、先明确:生命周期钩子对应关系(Vue2 ↔ Vue3)
| 阶段 | Vue2 选项式 API | Vue3 选项式 API | Vue3 组合式 API(setup 中) |
|---|---|---|---|
| 初始化 | beforeCreate | beforeCreate | setup(替代,无对应钩子) |
| 初始化 | created | created | setup(替代,无对应钩子) |
| 挂载前 | beforeMount | beforeMount | onBeforeMount |
| 挂载完成 | mounted | mounted | onMounted |
| 更新前 | beforeUpdate | beforeUpdate | onBeforeUpdate |
| 更新完成 | updated | updated | onUpdated |
| 销毁前 | beforeDestroy | beforeUnmount | onBeforeUnmount |
| 销毁完成 | destroyed | unmounted | onUnmounted |
关键:Vue3 组合式 API 中,
setup执行时机等价于beforeCreate + created,无需再写这两个钩子;销毁钩子名称从beforeDestroy/destroyed改为beforeUnmount/unmounted,语义更清晰。
二、核心执行顺序(分 3 大阶段)
阶段 1:挂载阶段(首次渲染)
核心逻辑:父组件先完成「初始化」,再触发子组件初始化,子组件完全挂载后,父组件才完成挂载。
完整执行顺序(Vue2/Vue3 通用逻辑):
父 beforeCreate → 父 created → 父 beforeMount
→ 子 beforeCreate → 子 created → 子 beforeMount
→ 子 mounted
→ 父 mounted
代码示例(Vue3 组合式 API)
<!-- 父组件 Parent.vue -->
<template>
<Child />
</template>
<script setup>
import { onBeforeMount, onMounted } from 'vue';
import Child from './Child.vue';
console.log('父 setup(等价于 beforeCreate/created)');
onBeforeMount(() => console.log('父 beforeMount'));
onMounted(() => console.log('父 mounted'));
</script>
<!-- 子组件 Child.vue -->
<script setup>
import { onBeforeMount, onMounted } from 'vue';
console.log('子 setup(等价于 beforeCreate/created)');
onBeforeMount(() => console.log('子 beforeMount'));
onMounted(() => console.log('子 mounted'));
</script>
控制台输出(验证顺序):
父 setup(等价于 beforeCreate/created)
父 beforeMount
子 setup(等价于 beforeCreate/created)
子 beforeMount
子 mounted
父 mounted
阶段 2:更新阶段(数据变化触发重渲染)
更新阶段分两种场景,执行顺序差异较大:
场景 1:子组件自身数据变化(仅子更新)
子 beforeUpdate → 子 updated
场景 2:父组件数据变化(触发子更新)
核心逻辑:父先进入更新前状态,再触发子更新,子更新完成后父才完成更新。
完整执行顺序:
父 beforeUpdate
→ 子 beforeUpdate → 子 updated
→ 父 updated
代码示例(父数据驱动子更新)
<!-- 父组件 Parent.vue -->
<template>
<Child :msg="parentMsg" />
<button @click="parentMsg = '更新后'">更新父数据</button>
</template>
<script setup>
import { ref, onBeforeUpdate, onUpdated } from 'vue';
import Child from './Child.vue';
const parentMsg = ref('初始值');
onBeforeUpdate(() => console.log('父 beforeUpdate'));
onUpdated(() => console.log('父 updated'));
</script>
<!-- 子组件 Child.vue -->
<template>{{ msg }}</template>
<script setup>
import { onBeforeUpdate, onUpdated } from 'vue';
defineProps(['msg']);
onBeforeUpdate(() => console.log('子 beforeUpdate'));
onUpdated(() => console.log('子 updated'));
</script>
点击按钮后控制台输出:
父 beforeUpdate
子 beforeUpdate
子 updated
父 updated
阶段 3:销毁阶段(组件卸载)
核心逻辑:父先触发销毁前状态,再触发子销毁,子完全销毁后父才完成销毁。
完整执行顺序:
父 beforeUnmount
→ 子 beforeUnmount → 子 unmounted
→ 父 unmounted
代码示例(父组件卸载触发子销毁)
<!-- 父组件 Parent.vue -->
<template>
<button @click="showChild = false">卸载子组件</button>
<Child v-if="showChild" />
</template>
<script setup>
import { ref, onBeforeUnmount, onUnmounted } from 'vue';
import Child from './Child.vue';
const showChild = ref(true);
onBeforeUnmount(() => console.log('父 beforeUnmount'));
onUnmounted(() => console.log('父 unmounted'));
</script>
<!-- 子组件 Child.vue -->
<script setup>
import { onBeforeUnmount, onUnmounted } from 'vue';
onBeforeUnmount(() => console.log('子 beforeUnmount'));
onUnmounted(() => console.log('子 unmounted'));
</script>
点击按钮后控制台输出:
父 beforeUnmount
子 beforeUnmount
子 unmounted
父 unmounted
三、关键注意事项(开发避坑)
1. 父组件调用子组件方法/数据的时机
- 必须在「子组件 mounted 之后」调用(比如父的 mounted 钩子,因为此时子已挂载完成);
- 若父在 created 中调用子方法,子组件尚未挂载,会报错
undefined。
2. 异步数据对生命周期的影响
- 父组件
created中请求接口(异步),数据返回时子组件可能已挂载完成,需通过watch监听数据变化再更新子组件; - 子组件若依赖父传递的异步数据,需在
watch或onUpdated中处理,而非mounted(可能数据尚未返回)。
3. 销毁阶段的清理工作
- 子组件的定时器、事件监听、请求取消等,必须在
beforeUnmount/unmounted中清理(否则会导致内存泄漏); - 父组件无需替子组件清理,因为子会先完成销毁,自身清理逻辑优先执行。
4. Vue3 组合式 API 特殊点
setup中无法访问this,且执行时机最早(父 setup → 子 setup);- 若需在 setup 中操作 DOM,需放在
onMounted中(DOM 已挂载)。
四、总结:核心规律速记
| 阶段 | 核心顺序 | 开发常用场景 |
|---|---|---|
| 挂载 | 父初始化 → 子初始化 → 子挂载 → 父挂载 | 父 mounted 中调用子组件方法 |
| 更新 | 父更新前 → 子更新 → 父更新完成 | 监听子组件更新后同步数据 |
| 销毁 | 父销毁前 → 子销毁 → 父销毁完成 | 子组件清理定时器/事件监听 |
一句话记住:「挂载时子先完,销毁时子先完;更新看数据,父变子更,子变自更」。
实际开发中,无需死记所有顺序,核心抓住「父等子挂载、子先销毁」的原则,结合 watch 处理数据依赖,即可规避绝大多数生命周期相关问题。
更多推荐


所有评论(0)