JAVASCRIPT
Implementing a Global Event Bus with `mitt` for Cross-Component Communication
Discover how to use the lightweight `mitt` library to create a global event bus in Vue 3, enabling simple, decoupled communication between any components in your application.
// utils/eventBus.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
// ComponentA.vue
<template>
<div class="component-a">
<h3>Component A</h3>
<p>Received Message: {{ receivedMessage }}</p>
<button @click="sendMessage">Emit Message</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import eventBus from './utils/eventBus';
const receivedMessage = ref('None');
onMounted(() => {
eventBus.on('custom-event', handleCustomEvent);
});
onBeforeUnmount(() => {
eventBus.off('custom-event', handleCustomEvent);
});
const handleCustomEvent = (payload) => {
receivedMessage.value = payload;
console.log('Component A received:', payload);
};
const sendMessage = () => {
eventBus.emit('another-event', 'Message from A!');
console.log('Component A emitted "another-event"');
};
</script>
<style scoped>
.component-a { border: 1px solid #aaddaa; padding: 15px; margin: 10px; border-radius: 5px; }
</style>
// ComponentB.vue
<template>
<div class="component-b">
<h3>Component B</h3>
<p>Received Message: {{ receivedMessageB }}</p>
<button @click="sendMessageToA">Emit Message to A</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import eventBus from './utils/eventBus';
const receivedMessageB = ref('None');
onMounted(() => {
eventBus.on('another-event', handleAnotherEvent);
});
onBeforeUnmount(() => {
eventBus.off('another-event', handleAnotherEvent);
});
const handleAnotherEvent = (payload) => {
receivedMessageB.value = payload;
console.log('Component B received:', payload);
};
const sendMessageToA = () => {
eventBus.emit('custom-event', 'Hello from Component B!');
console.log('Component B emitted "custom-event"');
};
</script>
<style scoped>
.component-b { border: 1px solid #ddaadd; padding: 15px; margin: 10px; border-radius: 5px; }
</style>
// App.vue
<template>
<div>
<h1>Event Bus Example</h1>
<ComponentA />
<ComponentB />
</div>
</template>
<script setup>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
</script>
How it works: This snippet demonstrates how to create and use a global event bus in Vue 3 for decoupled component communication, using the lightweight `mitt` library. `eventBus.js` exports a `mitt` instance. `ComponentA` listens for `'custom-event'` and emits `'another-event'`, while `ComponentB` does the opposite. Components subscribe to events using `eventBus.on()` in `onMounted` and clean up listeners using `eventBus.off()` in `onBeforeUnmount` to prevent memory leaks. This pattern is useful for communication between components that don't have a direct parent-child relationship.