Vue.js 父子组件通信模式比较 
1. Props 与 Events(单向数据流) 
1.1 实现方式 
- Props 向下传递:父组件通过属性绑定向子组件传递数据
html
<child-component :message="parentMessage"></child-component>- Events 向上传递:子组件通过 $emit触发自定义事件
javascript
// 子组件
this.$emit('update', newValue)1.2 优点 
- 符合单向数据流原则,数据流向清晰
- 明确的父子关系,便于调试和维护
- Vue DevTools 支持完整的事件追踪
1.3 缺点 
- 深层嵌套时需要逐层传递(prop drilling)
- 需要编写模板语法和事件处理逻辑
- 子组件不能直接修改 props(需要配合事件)
2. v-model 双向绑定 
2.1 实现方式 
html
<child-component v-model="parentData"></child-component>等价于:
html
<child-component 
  :value="parentData"
  @input="parentData = $event">
</child-component>2.2 优点 
- 简化双向绑定的模板代码
- 符合表单元素的交互习惯
- 支持自定义 model 配置(Vue 2.2+)
2.3 缺点 
- 可能违反单向数据流原则
- 仅适用于单个值的双向绑定
- 需要严格遵循 value+input的命名约定
3. .sync 修饰符(Vue 2.3+) 
3.1 实现方式 
html
<child-component :title.sync="parentTitle"></child-component>子组件通过:
javascript
this.$emit('update:title', newTitle)3.2 优点 
- 支持多个属性的双向绑定
- 比完整 v-model 更灵活
- 显式声明更新事件
3.3 缺点 
- Vue 3 中已被合并到 v-model
- 可能造成隐式数据流
- 需要维护事件命名规范
4. $refs 直接访问 
4.1 实现方式 
html
<child-component ref="childRef"></child-component>父组件通过:
javascript
this.$refs.childRef.methodName()4.2 优点 
- 可直接调用子组件方法
- 适用于紧急修复或原型开发
- 方便访问 DOM 元素
4.3 缺点 
- 破坏组件封装性
- 导致强耦合
- 无法响应式更新
- 违反单向数据流原则
5. Provide/Inject 
5.1 实现方式 
javascript
// 父组件
provide() {
  return { theme: this.theme }
}
// 子组件
inject: ['theme']5.2 优点 
- 解决深层嵌套组件通信
- 避免 prop drilling
- 支持响应式数据(配合对象类型)
5.3 缺点 
- 数据流向不够透明
- 可能造成命名冲突
- 降低组件可复用性
6. 事件总线(Event Bus) 
6.1 实现方式 
javascript
// event-bus.js
import Vue from 'vue'
export default new Vue()
// 组件 A
eventBus.$emit('event-name', data)
// 组件 B
eventBus.$on('event-name', handler)6.2 优点 
- 实现跨层级通信
- 解耦组件关系
- 支持一对多通信
6.3 缺点 
- 难以追踪事件来源
- 可能造成内存泄漏
- 不适合大型项目
综合比较表 
| 方法 | 数据流向 | 适用场景 | 维护成本 | Vue 3 兼容性 | 
|---|---|---|---|---|
| Props/Events | 单向 | 简单父子通信 | 低 | ✅ | 
| v-model | 双向 | 表单组件 | 中 | ✅(改进) | 
| .sync | 双向 | 多个属性更新 | 中 | ❌(合并) | 
| $refs | 任意 | 紧急修复/访问 DOM | 高 | ✅ | 
| Provide/Inject | 任意 | 深层嵌套 | 中 | ✅ | 
| Event Bus | 任意 | 跨组件通信 | 高 | ✅(可选) | 
最佳实践建议 
- 优先使用 Props/Events 维护单向数据流
- 表单交互场景使用 v-model
- 深层嵌套使用 Provide/Inject
- 避免在业务逻辑中过度使用 $refs
- 复杂应用建议采用 Vuex/Pinia 状态管理
组件通信复杂度与项目规模的关系可以用公式表示:
其中 是组件数量, 是采用的优化模式数量。