uni-app中父子组件mounted顺序不可靠,因受Vue版本、平台及customComponent配置三重影响;应使用nextTick访问$refs、onReady替代mounted、事件或状态驱动通信。

onLoad 和 onShow 不是父子组件生命周期,而是页面级钩子;真正容易混乱的是组件级的 created、mounted、onMounted 等 —— 尤其在父子嵌套 + uni-app 多端编译下,顺序不一致是常态,不是 bug。
uni-app 中父子组件 mounted 顺序为什么不可靠
因为 uni-app 的组件挂载流程受三重影响:Vue 版本(v2/v3)、平台(App/H5/小程序)、是否使用 customComponent: true(如微信小程序自定义组件模式)。例如:
- 在 H5 端,父
mounted总是先于子mounted(符合 Vue 原生逻辑) - 但在微信小程序端,若子组件是通过
custom-component编译的,子组件可能提前触发ready(等价于mounted),而父组件的mounted还没执行 - App 端(nvue)更特殊:
mounted可能根本不会触发,必须用onReady替代
所以不要依赖「父 mounted 后子一定已 mounted」这个假设。
用 nextTick + $refs 安全访问子组件状态
当父组件需要在自身 mounted 后操作子组件 DOM 或调用方法时,直接访问 this.$refs.childRef 可能为 undefined,尤其在小程序端。
- 必须包裹在
this.$nextTick(() => { /* 访问 this.$refs.childRef */ })中(Vue 2) - Vue 3 Composition API 下改用
nextTick(() => { /* ... */ }),且确保子组件已声明defineExpose - 避免在父
mounted里直接调用子组件方法,改用watch监听子组件暴露的响应式状态,或用onUpdated配合条件判断
跨端统一用 onReady 替代 mounted 处理 DOM 依赖逻辑
uni-app 官方推荐在页面或组件中优先使用 onReady(而非 mounted)来处理真实 DOM 操作,因为它在所有平台都保证节点已就绪:
-
onReady在页面/组件首次渲染完成、DOM 可访问时触发,比mounted更稳定 - 在 Vue 2 项目中,可在
export default里直接写onReady() { ... } - Vue 3 +
setup中需用onReady(来自@dcloudio/uni-app)而不是onMounted - 注意:
onReady不会像mounted那样在热更新后重复触发,适合一次性初始化
父子通信别卡在生命周期顺序上,改用事件或状态驱动
如果业务逻辑被“谁先 mounted”卡住,说明设计耦合过重。实际应:
- 子组件通过
defineExpose(Vue 3)或export default的methods暴露能力,父组件按需调用,不强求时机 - 用
uni.$emit/uni.$on或mitt实现松耦合通信,触发时机由业务动作决定(如按钮点击、数据变更),而非生命周期 - 对异步加载场景,用
v-if="loaded"控制子组件渲染,让子组件自己管理内部生命周期,父组件只管传参和监听结果
最常被忽略的一点:uni-app 的 onLoad 是页面级、同步执行的,但它和组件 created 之间没有执行序保障 —— 别在 onLoad 里直接读取子组件 data,那大概率是空的。


















