vue3组件通信汇总
Vue3 组件通信方式汇总
1. 父子组件通信
- props:父传子,单向数据流。
- emits:子传父,事件机制。
<!-- 父组件 -->
<ChildComponent :message="parentMessage" @child-event="handleEvent" />
<script setup>
import { ref } from "vue";
const parentMessage = ref("Hello from parent");
const handleEvent = (payload) => {
console.log("Received from child:", payload);
};
</script>
<!-- 子组件 -->
<script setup>
const props = defineProps({ message: String });
const emit = defineEmits(["child-event"]);
const sendToParent = () => {
emit("child-event", "Hello from child");
};
</script>
2. 非父子组件通信
2.1 Event Bus(事件总线)
适合低频、简单事件传递,不推荐大规模使用。
eventBus.js
import mitt from "mitt";
export default mitt();
使用:
<script setup>
import eventBus from "./eventBus";
eventBus.emit("custom-event", { data: "payload" });
eventBus.on("custom-event", (payload) => {
/* ... */
});
</script>
3. 状态管理库(Pinia/Vuex)
适合复杂/全局状态管理。
// stores/counter.js
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
},
},
});
<script setup>
import { useCounterStore } from "@/stores/counter";
const counterStore = useCounterStore();
counterStore.increment();
</script>
4. Provide/Inject
适合跨多层级传递数据(如主题、上下文等)。
// 顶层组件
<script setup>
import { provide, ref } from "vue";
const sharedState = ref("Shared Data");
provide("sharedState", sharedState);
</script>
// 深层子组件
<script setup>
import { inject } from "vue";
const sharedState = inject("sharedState");
</script>
5. VueUse 工具库
适合简单全局状态,推荐 createGlobalState。
// composables/useGlobalState.js
import { createGlobalState } from "@vueuse/core";
export const useGlobalState = createGlobalState(() => {
const count = ref(0);
const increment = () => {
count.value++;
};
return { count, increment };
});
<script setup>
import { useGlobalState } from "@/composables/useGlobalState";
const globalState = useGlobalState();
</script>
6. Web Storage
适合持久化数据(如用户信息、token 等)。
// utils/storage.js
export const setStorage = (key, value) =>
localStorage.setItem(key, JSON.stringify(value));
export const getStorage = (key) => {
const value = localStorage.getItem(key);
return value ? JSON.parse(value) : null;
};
<script setup>
import { setStorage, getStorage } from "@/utils/storage";
setStorage("user", { name: "John" });
const user = ref(getStorage("user"));
</script>
7. Vue Router 路由参数
适合页面间传递数据。
// router.js
{ path: '/user/:id', name: 'User', component: UserComponent }
<script setup>
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
router.push({ name: "User", params: { id: 123 } });
const route = useRoute();
const userId = route.params.id;
</script>
8. Broadcast Channel API
适合多窗口/标签页通信。
// utils/broadcast.js
const channel = new BroadcastChannel("app-channel");
export const sendMessage = (message) => channel.postMessage(message);
export const onMessage = (callback) => {
channel.onmessage = (event) => callback(event.data);
};
<script setup>
import { sendMessage, onMessage } from "@/utils/broadcast";
sendMessage({ type: "update", data: "new data" });
onMessage((data) => {
console.log("Received:", data);
});
</script>
通信方式选择指南
| 场景 | 推荐方式 |
|---|---|
| 父子组件 | props + emits |
| 跨层级组件 | Provide/Inject |
| 复杂状态管理 | Pinia/Vuex |
| 简单全局状态 | VueUse createGlobalState |
| 跨窗口/标签页 | Broadcast Channel |
| 持久化数据 | Web Storage |
| 路由页面间传递 | 路由参数 |
| 低频事件 | Event Bus |
注意事项
- Event Bus:避免滥用,事件多时难以维护,优先用状态管理。
- Provide/Inject:层级深时数据流不清晰,需谨慎。
- 状态管理库:复杂应用建议 Pinia/Vuex,利于维护和调试。
- 性能:频繁大数据更新避免全局事件。
- 类型安全:Vue3+TypeScript 推荐强类型定义通信接口。

浙公网安备 33010602011771号