HLJ 发布于
2025-05-22 15:50:18
0阅读

Vue3同级组件事件传递方法总结

在 Vue3 中,同级组件之间触发事件需要通过共享父组件全局事件总线(Event Bus)状态管理(如 Pinia) 实现。以下是具体方法:


方法 1:通过共同父组件传递

通过父组件作为“中介”,子组件 A 触发事件,父组件监听并传递给子组件 B。

实现步骤:

  1. 子组件 A 触发事件并传递数据给父组件。
  2. 父组件 监听事件,更新数据或调用方法。
  3. 子组件 B 通过 props 或父组件方法接收数据。

代码示例:

<!-- 父组件 Parent.vue -->
<template>
  <ChildA @event-from-a="handleEventA" />
  <ChildB :message="message" />
</template>

<script setup>
import { ref } from 'vue';
import ChildA from './ChildA.vue';
import ChildB from './ChildB.vue';

const message = ref('');

const handleEventA = (data) => {
  message.value = data; // 更新数据传递给 ChildB
};
</script>
<!-- 子组件 ChildA.vue -->
<template>
  <button @click="triggerEvent">触发事件</button>
</template>

<script setup>
const emit = defineEmits(['event-from-a']);

const triggerEvent = () => {
  emit('event-from-a', '来自 ChildA 的数据');
};
</script>

方法 2:全局事件总线(Event Bus)

使用第三方库(如 mitt)创建一个全局事件总线,实现组件间直接通信。

实现步骤:

  1. 安装 mittnpm install mitt
  2. 创建事件总线实例。
  3. 子组件 A 触发事件,子组件 B 监听事件。

代码示例:

// eventBus.js
import mitt from 'mitt';
export const emitter = mitt();
<!-- 子组件 ChildA.vue -->
<script setup>
import { emitter } from './eventBus';

const triggerEvent = () => {
  emitter.emit('custom-event', '来自 ChildA 的数据');
};
</script>
<!-- 子组件 ChildB.vue -->
<script setup>
import { emitter } from './eventBus';
import { onMounted, onUnmounted } from 'vue';

const handleEvent = (data) => {
  console.log('收到数据:', data);
};

onMounted(() => {
  emitter.on('custom-event', handleEvent);
});

onUnmounted(() => {
  emitter.off('custom-event', handleEvent); // 清理监听
});
</script>

方法 3:使用 Pinia(状态管理)

通过共享状态和响应式数据触发组件间通信。

实现步骤:

  1. 安装 Pinia:npm install pinia
  2. 创建 Store 存储共享状态。
  3. 子组件 A 更新 Store,子组件 B 监听 Store 变化。

代码示例:

// stores/useEventStore.js
import { defineStore } from 'pinia';

export const useEventStore = defineStore('event', {
  state: () => ({
    message: '',
  }),
  actions: {
    setMessage(data) {
      this.message = data;
    },
  },
});
<!-- 子组件 ChildA.vue -->
<script setup>
import { useEventStore } from './stores/useEventStore';

const eventStore = useEventStore();

const triggerEvent = () => {
  eventStore.setMessage('来自 ChildA 的数据');
};
</script>
<!-- 子组件 ChildB.vue -->
<script setup>
import { useEventStore } from './stores/useEventStore';
import { storeToRefs } from 'pinia';

const eventStore = useEventStore();
const { message } = storeToRefs(eventStore); // 响应式监听
</script>

<template>
  <div>{{ message }}</div>
</template>

方法对比

方法 适用场景 优点 缺点
父组件传递 简单场景,少量层级 无需额外依赖,逻辑清晰 层级深时繁琐
全局事件总线 跨组件通信,解耦 灵活,适合任意组件通信 需手动管理监听,可能内存泄漏
Pinia 状态管理 中大型项目,共享状态 集中管理数据,响应式自动更新 需要学习成本,略复杂

选择依据:

  • 简单场景:父组件传递。
  • 解耦需求:全局事件总线。
  • 复杂状态:Pinia。
当前文章内容为原创转载请注明出处:http://www.good1230.com/detail/2025-05-22/725.html
最后生成于 2025-06-05 15:00:49
此内容有帮助 ?
0