Vue 组件通信方式根据组件关系和应用场景可分为多种方案,以下是主要分类及实现方法:
⚙️ 一、父子组件通信
-
Props(父 → 子)
父组件通过属性传递数据,子组件用props
接收。<!-- 父组件 --> <Child :title="parentData" /> <!-- 子组件 --> <script setup> const props = defineProps(['title']); </script>
-
**emit/自定义事件(子→父)∗∗子组件通过‘emit / 自定义事件(子 → 父)** 子组件通过 `emit/自定义事件(子→父)∗∗子组件通过‘emit` 触发事件,父组件监听处理。
<!-- 子组件 --> <button @click="$emit('update', data)">提交</button> <!-- 父组件 --> <Child @update="handleUpdate" />
-
ref / $parent / $children
ref
:父组件通过ref
访问子组件实例或 DOM。$parent
/$children
:直接访问父/子实例(Vue3 中$children
移除)。
<!-- 父组件 --> <Child ref="childRef" /> <script setup> import { ref } from 'vue'; const childRef = ref(); childRef.value.childMethod(); // 调用子组件方法 </script>
🔄 二、跨层级组件通信
-
provide / inject
祖先组件提供数据,后代组件注入使用。<!-- 祖先组件 --> <script setup> import { provide } from 'vue'; provide('theme', 'dark'); </script> <!-- 后代组件 --> <script setup> import { inject } from 'vue'; const theme = inject('theme'); </script>
-
$attrs / $listeners
$attrs
:传递未在props
中声明的属性(如class
,style
)。$listeners
:传递事件监听器(Vue3 合并到$attrs
)。
<!-- 父组件 --> <Child :msg="message" @custom-event="handler" /> <!-- 子组件 --> <Grandchild v-bind="$attrs" /> <!-- 继续向下传递 -->
🌐 三、任意组件通信
-
Event Bus(全局事件总线)
创建 Vue 实例作为事件中心(Vue3 推荐使用mitt
等库)。// eventBus.js(Vue2) const bus = new Vue(); export default bus; // 组件A:发送事件 bus.$emit('message', data); // 组件B:监听事件 bus.$on('message', handler);
-
Vuex / Pinia(状态管理)
集中式状态管理,适用于中大型项目。- Vuex:Vue2 官方状态库。
- Pinia:Vue3 推荐的状态管理方案,更简洁。
// Pinia 示例 import { defineStore } from 'pinia'; export const useStore = defineStore('main', { state: () => ({ count: 0 }), actions: { increment() { this.count++ } } });
💎 四、Vue3 新增特性
-
defineExpose(暴露组件方法)
通过<script setup>
显式暴露属性或方法。<!-- 子组件 --> <script setup> const publicMethod = () => {}; defineExpose({ publicMethod }); </script>
-
v-model 增强
支持多个v-model
绑定及自定义修饰符。<!-- 父组件 --> <Child v-model:title="pageTitle" v-model:content="pageContent" />
📊 通信方式对比与选型建议
通信方式 | 适用场景 | 特点 | 版本支持 |
---|---|---|---|
Props / $emit | 父子组件简单数据传递 | 官方基础方案,单向数据流 | Vue2/3 |
provide / inject | 跨多层组件传递数据 | 避免逐层传递,响应式数据支持 | Vue2/3 |
Event Bus | 任意组件事件通信(小型项目) | 轻量但需注意事件销毁 | Vue2 |
Vuex / Pinia | 复杂状态共享 | 集中管理,支持调试工具 | Vue2/3 |
$attrs / $listeners | 透传属性与事件 | 简化多层组件属性传递 | Vue2/3 |
最佳实践:
- 父子通信首选 Props + $emit。
- 跨层级数据用 provide / inject。
- 全局状态管理用 Pinia(Vue3) 或 Vuex(Vue2)。
- 避免滥用
$parent
或ref
直接修改数据,保持数据流清晰。