$parent和$children是vue中能用但需慎用的应急手段,官方推荐优先使用props和$emit;$parent可访问父实例方法但不保证属性存在,$children为非响应式数组且顺序不保证,二者均绕过响应式系统、不利于维护与类型安全。

直接用 $parent 或 $children 通信不是首选方案,它属于“能用但要慎用”的底层能力。Vue 官方明确建议优先使用 props 和 $emit,而把 $parent/$children 当作应急手段。
什么时候可能用到 $parent
子组件需要快速调用父组件的某个方法,且该方法不涉及状态管理、不需响应式更新,也不打算复用到其他上下文中:
- 比如子组件是一个弹窗按钮,点击后想直接触发父组件的
openModal()方法 - 子组件内部表单校验失败,想让父组件滚动到错误区域,调用
this.$parent.scrollToError() - 调试阶段临时读取父组件的某个临时数据(如
this.$parent.debugMode)
注意:this.$parent 拿到的是父组件实例,可访问其 data、methods、computed,但不能保证父组件一定有这些属性——一旦父组件更换,代码容易报错。
什么时候可能用到 $children
父组件需要批量操作多个同类型子组件,又不想为每个都加 ref:
- 比如一个表单容器组件,内部有若干自定义输入框子组件,父组件统一调用所有子组件的
validate()方法 - 动画控制场景:父组件触发所有子组件执行
startAnimation() - 收集子组件当前状态(如所有子组件的
isDirty值)
但要注意:this.$children 是非响应式数组,顺序不保证,也不包含异步加载或 v-if 为 false 的子组件。若子组件结构变动,索引容易错位,比如 this.$children[1] 下次可能指向完全不同的组件。
$parent 与 $children 的硬性限制
这两者都不是 Vue 设计的“标准通信机制”,而是实例上的内部属性,因此存在几个关键约束:
-
$children不是响应式——子组件增删不会触发父组件更新,也不能用v-for直接遍历渲染 -
$parent在根组件(App)中为undefined;嵌套在多个层级时,$parent只指向直接父级,无法跨层获取 - 两者都绕过了 Vue 的响应式系统和数据流规范,容易导致难以追踪的数据变更,不利于测试和维护
- 在 TypeScript 项目中,类型推导困难,需手动断言类型,增加出错风险
更稳妥的替代方案
多数情况下,可以用更清晰、更可控的方式代替:
- 用
ref替代$children:给目标子组件加ref="xxx",通过this.$refs.xxx精准访问,支持类型提示 - 用
provide / inject替代深层$parent访问:适合跨多层传递配置或工具方法,解耦更强 - 用事件总线或状态库(Pinia)替代复杂父子联动:当逻辑变重、组件复用性提高时,值得升级通信模型
- 保持单向数据流:父传子用
props,子传父用$emit,这是最易理解、最易调试的路径
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











