Event Bus (PubSub) in Vue 3

Event Bus (PubSub) in Vue 3

Vue.js - The Progressive JavaScript Framework

Reminiscent of removing native API fetching in Vue 2 in favor of encouraging the use of third party libraries (most recommended being Axios), Vue 3 also has a breaking change: event bussing. Well, technically, Vue just wants you to only emit from parent⟵child (and parent⟶child bussing would be through the use of props). They've never officially encouraged developers to create an event bus outside of the main Vue instance because some consider it anti-pattern to the Vue methodology; outside of the parent⟷child emit/prop pattern, they encourage developers to use VueX when that pattern is too limiting. The downside is VueX can be overkill for a lot of smaller projects, so you'll see a ton of event bus articles and tutorials using this publish-subscribe or "pubsub" pattern through a Google search.

In Vue 2

Previously, you'd create an event bus in the base of your project through a separate Vue instance, which you'd then use throughout your application to bus events/data between parent and child using their Events API:

/* main.js */
import Vue from 'vue';
export const bus = new Vue();

... init main Vue application ...

Emit the event in Component A

/* ComponentA.vue */
<template>
  <div>
    <button @click="bus.$emit('say-hello', 'Hey, Stranger!')">Emit Event!</button>
  </div>
</template>

<script>
import { bus } from '../main'
export default {
  name: 'ComponentA',

...

Listen for the event in Component B

/* ComponentB.vue */
<script>
import { bus } from '../main';
export default {
  name: 'ComponentB',
  created (){
    bus.$on('say-hello', (greeting) => alert(greeting))
  }
}
</script>

In Vue 3 this is no longer possible because while $emit still works for child->parent communication, $on, $off, and $once are no longer available to the instance (more about that here).

So, what do we do in Vue 3?

Luckily it's really simple to add an external library to handle it for us in much the same way. In this example, I'll use Mitt. I'll use emitter instead of bus which follows their example code and hopefully makes it easier to spot the difference having used bus in the previous example.

/* main.js */
import App from '@/App.vue'
import mitt from 'mitt'
import { createApp } from 'vue'

const emitter = mitt()
const app = createApp(App)

app.config.globalProperties.emitter = emitter
app.mount('#app')

Emit the event in Component A

/* ComponentA.vue */
<template>
  <div>
    <button @click="emitter.emit('say-hello', 'Hey, Stranger!')">Emit Event!</button>
  </div>
</template>

<script>
export default {
  name: 'ComponentA',

...

Listen for the event in Component B

/* ComponentB.vue */
<script>
import { bus } from '../main';
export default {
  name: 'ComponentB',
  created (){
    this.emitter.on('say-hello', (greeting) => alert(greeting))
  }
}
</script>

In Conclusion

Ultimately, like any breaking change, it can be a hassle to update projects but in the end it ends up being pretty simple and the code looks largely the same. While certainly Vue's developers have their opinions on how they'd like to see Vue used, they've always done a great job of offering up compromises where their framework is still flexible when you add features or patterns outside of their normal workflow. The developer wins, too, because libraries like Mitt can focus on supporting features that are outside of Vue's feature scope.

vue emit publish-subscribe pubsub bus event

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

8 Popular Websites That Use The Vue.JS Framework

In this article, we are going to list out the most popular websites using Vue JS as their frontend framework. Vue JS is one of those elite progressive JavaScript frameworks that has huge demand in the web development industry. Many popular websites are developed using Vue in their frontend development because of its imperative features.

How To Create A Global Event Bus With Vue.js

How To Create A Global Event Bus With Vue.js. An event bus is the pub/sub pattern. Means one component publishes an event and another component subscribes to that event. So one component Vue component emits an event with some data, and another component subscribes to that event and receives that data.

Vue State Management with Publish & Subscribe pattern

vue-state-store. Simple state management system that full supports for typescript. Distributed state management module system for Vue. [Pub & Sub model based]

Vue File Upload Using vue-dropzone Tutorial

Vue File Upload Using vue-dropzone Tutorial is the leading topic. For this example, I am using Vue 3 and vue-dropzone library. We will create a simple form component through the user can upload the image, and we will store in the Laravel 5.6 server.

10 Best Vue Icon Component For Your Vue.js App

In this article, I will collect 10 Vue icon component to bring more interactivity, better UI design to your Vue application.