父子组件生命周期执行顺序是“父先于子挂载、子先于父销毁”,核心在于数据流与时机依赖;初次加载时执行顺序为:父beforeCreate→父created→父beforeMount→子beforeCreate→子created→子beforeMount→子mounted→父mounted。

父子组件生命周期执行顺序,核心是“父先于子挂载、子先于父销毁”,但通信出错往往卡在“子组件还没准备好,父组件就发消息”或“父组件已更新,子组件还用旧数据”。关键不是死记顺序,而是抓住数据流和时机依赖关系。
一、典型执行顺序(以 Vue 2/3 Options API 为例)
假设父组件 渲染子组件 ,初次加载时:
- 父 beforeCreate → 父 created(此时无 DOM,子组件实例尚未创建)
- 父 beforeMount(父模板编译完成,但未挂载;子组件开始初始化)
- 子 beforeCreate → 子 created → 子 beforeMount → 子 mounted(子组件完成挂载)
- 父 mounted(父组件 DOM 挂载完成,此时子组件已就绪)
⚠️ 注意:mounted 是第一个能安全访问子组件 DOM 和调用子方法的钩子。在 created 或 beforeMount 中直接操作子组件(如调用子组件方法、读取子组件 ref),大概率拿到 undefined 或空值。
二、常见通信时机错误及解法
多数问题源于“父等不及子”,或“子没监听到父的初始状态”。不靠猜,靠明确约定时机:
-
父传初始 prop 给子 → 子应在
mounted后再使用(尤其涉及 DOM 或异步逻辑);若需在created用,确保 prop 是同步可读的基本类型,且父组件未在data或computed中延迟计算 -
父通过
$refs调子方法 → 必须等mounted之后,推荐封装为事件:父 emit 事件,子在mounted中监听,避免强耦合调用时机 -
子通过
$emit通知父 → 可在created触发(只要事件不依赖 DOM),但父接收后若要操作子 DOM,仍需等子mounted完成——这时可用nextTick延迟执行 - 使用
v-model或 .sync 时,子组件必须在props变化后及时响应 → 避免在watch中直接操作 DOM,改用nextTick确保渲染完成
三、Vue 3 Composition API 的新注意点
setup() 执行早于所有选项式钩子(相当于 beforeCreate + created 合并):
-
setup()中无法访问this,也不能直接用ref拿到子组件实例(因为子还没创建) - 要用
onMounted(() => { /* 此时子组件已 mount */ })包裹对子组件的操作 - 父子响应式通信更推荐
defineProps/defineEmits+watch,而非依赖钩子顺序;例如监听 props 变化时,用watch(props, ...)并设{ immediate: true }处理初始值
四、调试小技巧
快速定位时机问题:
- 在每个生命周期钩子里加 console.log('Parent created')、console.log('Child mounted'),观察真实执行流
- 检查
ref是否为 null:父组件中if (this.$refs.child) this.$refs.child.doSomething(),比盲目调用更安全 - 用 Vue Devtools 查看组件状态树,确认子组件是否已渲染、props 是否已同步










