Event bus
An event bus is a shared emitter that unrelated components use to send messages to each other.
In this page:
Event bus
Vue 3 removed $on, $off and $once, so an event bus is now built with a small emitter such as mitt or a hand-written one. It decouples components but makes data flow hard to trace, so state management or provide/inject is usually a better choice for shared state.
Note:
Vue 3 no longer ships an event bus; use mitt or a store.
Example: Event bus
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<sender-btn></sender-btn>
<receiver-box></receiver-box>
</div>
<script>
const bus = { handlers: {}, on(e, f) { (this.handlers[e] ||= []).push(f); }, emit(e, d) { (this.handlers[e] || []).forEach((f) => f(d)); } };
const app = Vue.createApp({});
app.component("sender-btn", { template: '<button @click="send">Send</button>', methods: { send() { bus.emit("msg", "hello bus"); } } });
app.component("receiver-box", {
data() { return { last: "nothing yet" }; },
created() { bus.on("msg", (m) => (this.last = m)); },
template: "<p>Received: {{ last }}</p>",
});
app.mount("#app");
document.querySelector("button").click();
Vue.nextTick(() => console.log(document.querySelector("p").textContent));
</script>
</body>
</html>
<!-- Output:
Rendered: SendReceived: hello bus
console: Received: hello bus
-->
Live Example
Related Topics
Common Mistakes
- Using this.$on in Vue 3
- Forgetting to unsubscribe in unmounted
- Building app-wide state on events
Chapter Summary
- Vue 3 removed $on and $off
- Use a tiny emitter like mitt
- Unsubscribe when unmounting
- Prefer stores for shared state
🔒
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: