在 Vue3 中,同级组件之间触发事件需要通过共享父组件、全局事件总线(Event Bus) 或状态管理(如 Pinia) 实现。以下是具体方法:
通过父组件作为“中介”,子组件 A 触发事件,父组件监听并传递给子组件 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>
使用第三方库(如 mitt
)创建一个全局事件总线,实现组件间直接通信。
mitt
:npm install mitt
。// 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>
通过共享状态和响应式数据触发组件间通信。
npm install pinia
。// 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 状态管理 | 中大型项目,共享状态 | 集中管理数据,响应式自动更新 | 需要学习成本,略复杂 |
选择依据: