前言
在 Vue 3 中,组件之间的通信方式多种多样,具体选择取决于组件之间的关系(父子、兄弟、跨层级等)以及应用的复杂度。
以下是常见的几种通信方式:
父→子:Props
这是最基础、最常用的通信方式。
1 | <!-- Parent.vue --> |
子→父:Emits
子组件通过 emit 触发事件,父组件监听。
子组件
1 | <!-- Child.vue --> |
父组件
1 | <!-- Parent.vue --> |
定义多个事件
1 | <script setup> |
TS中定义多个事件
1 | <script setup lang="ts"> |
兄弟组件通信
兄弟组件通信:通过共同父组件中转
兄弟之间不能直接通信,通常借助父组件作为“中介”:
- 兄弟 A → 父(emit)
- 父 → 兄弟 B(props)
祖先→后代
使用 provide / inject
适用于祖先组件向深层后代传递数据,避免逐层 props 透传。
1 | <!-- Ancestor.vue --> |
注意:
provide/inject不适用于响应式更新,除非你注入的是ref或reactive对象。
全局状态管理
Pinia(推荐)或 Vuex
对于复杂应用,建议使用状态管理库。
Vue 3 官方推荐 Pinia。
安装
1 | npm install pinia |
注册Pinia
1 | // main.js |
stores/common.ts
1 | import { ref } from 'vue' |
使用
1 | <template> |
其他页面使用
1 | <template> |
事件总线
不推荐,但可行
Vue 3 移除了 $on, $emit 实例方法,但可用第三方库(如 mitt)实现事件总线:
1 | // eventBus.js |
注意:
事件总线容易导致代码难以维护,仅适合小型项目或临时方案。
调用子组件方法
模板引用(ref)访问子组件实例。
子组件使用defineExpose导出属性或方法。
父组件可通过 ref 直接调用子组件的方法或访问其数据(不推荐频繁使用,破坏封装性)。
1 | <!-- Parent.vue --> |
子组件
1 | <!-- Child.vue --> |
总结建议
| 场景 | 推荐方式 |
|---|---|
| 父子通信 | Props + Emits |
| 祖先→后代 | provide / inject |
| 全局共享状态 | Pinia |
| 兄弟通信 | Pinia 或 通过父组件中转 |
| 紧耦合交互(如表单控件) | ref + defineExpose |