Vue3 跨组件通信完整方案对比总结
🌈Vue3 跨组件通信完整方案对比总结
👉 收藏 + 点赞 + 关注,一文搞定组件通信!
一、前言
在 Vue3 中,组件间通信有多种技术方案。每种方案适用于不同场景,没有绝对优劣,合理选型最重要。
二、通信方案全景图
通信方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
props / emit | 父子组件通信 | 简单、官方推荐、类型安全 | 只能父子使用,嵌套层级深时繁琐 |
provide / inject | 跨层级祖孙组件 | 跨多层组件方便 | 松散耦合,不适合频繁数据变更 |
ref / expose | 父组件操作子组件方法 | 直观易用 | 只能父对子使用 |
mitt (事件总线) | 任意组件 | 跨层简单快速、轻量 | 需手动解绑,易混乱 |
状态管理(Pinia、Vuex) | 全局状态管理 | 规范、集中、易维护 | 引入成本较高 |
URL Params | 路由级通信 | 深度路由传参 | 仅适用于路由通信 |
三、每个方案详细讲解
1️⃣ props / emit
(父子通信)
适用:
- 父传子(props)
- 子传父(emit)
示例:
<!-- 父组件 -->
<Child :msg="parentMsg" @updateMsg="handleUpdate" />
<!-- 子组件 -->
<template>{{ msg }}</template>
<script setup>
const props = defineProps<{ msg: string }>();
const emit = defineEmits<['updateMsg']>;
emit('updateMsg', '新值');
</script>
优缺点:
- ✅ 官方标准
- ✅ TS 友好
- ❌ 只能父子通信
2️⃣ provide / inject
(祖孙通信)
适用:
- 深层嵌套组件
- 全局注入轻量数据
示例:
<!-- 祖先组件 -->
provide('username', '张三');
<!-- 任意子孙组件 -->
const username = inject('username');
优缺点:
- ✅ 解耦
- ❌ 数据响应性弱,需手动 ref
provide('username', ref('张三'));
const username = inject('username') as Ref<string>;
3️⃣ ref / expose
(父操作子)
适用:
- 父组件调用子组件方法、属性
示例:
<!-- 子组件 -->
<script setup>
function openModal() { /* ... */ }
defineExpose({ openModal });
</script>
<!-- 父组件 -->
<Child ref="childRef" />
childRef.value?.openModal();
优缺点:
- ✅ 操作方便
- ❌ 只能父对子,适用面小
4️⃣ mitt
(事件总线)
适用:
- 跨任意组件
- 轻量快速
封装示例:
import mitt from 'mitt';
export const eventBus = mitt();
使用示例:
eventBus.emit('login', user);
eventBus.on('login', (user) => { ... });
优缺点:
- ✅ 极轻量
- ✅ 不限层级
- ❌ 手动解绑,长期使用需规范管理
5️⃣ 状态管理(推荐 Pinia)
适用:
- 全局状态
- 复杂业务逻辑
示例:
// store/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {state: () => ({ username: '张三' }),
});
const store = useUserStore();
store.username = '李四';
优缺点:
- ✅ 全局统一管理
- ✅ TS 完美支持
- ❌ 初学者学习成本稍高
6️⃣ URL Params(路由通信)
适用:
- 页面跳转传参
示例:
router.push({ name: 'detail', query: { id: 123 } });
const route = useRoute();
console.log(route.query.id);
优缺点:
- ✅ 路由通信标准方案
- ❌ 仅适合路由传参
四、快速选型建议表
场景 | 推荐方案 |
---|---|
简单父子组件传值 | props / emit |
深层嵌套祖孙组件传值 | provide / inject |
父调用子组件内部方法 | ref / expose |
任意组件快速通信 | mitt |
项目级全局状态管理 | Pinia |
路由跳转时传参 | URL Params |
五、最终建议
- 👉 小项目:
props / emit
+provide/inject
+mitt
- 👉 中大型项目:强烈建议引入 Pinia 状态管理