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 推荐强类型定义通信接口。
posted @ 2025-07-14 15:12  混名汪小星  阅读(25)  评论(0)    收藏  举报