DEV Community

Parag Chirde
Parag Chirde

Posted on

Event bus in Nuxt3

Event bus is typically a mechanism that makes it possible to have communication between different components. These components can be present at any level of component hierarchy in your project.

To know more about Event bus and its implementation in Nuxt2 visit link

VueJS Eventbus: Easy way to pass data between components

However, the official documentation you can see how the Event Bus implementation has changed from Vue 2 to Vue 3.

Introducing mitt, a new and simple way of implementing event bus on Vue3/Nuxt3

We’ll start by installing mitt.

npm i mitt
Enter fullscreen mode Exit fullscreen mode

Next we’ll register a new plugin named mitt.client.js in the plugins directory.

import mitt from "mitt";
const emitter = mitt();
export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.provide('bus', {
      $on: emitter.on,
      $emit: emitter.emit,
    })
  })
Enter fullscreen mode Exit fullscreen mode

Know more about registering plugins in Nuxt3 here

Let’s see how to emit and listen to events in different components. Consider two components A and B. In our case Component A will emit the event and Component B will listen to the event.

ComponentA.js

this.$bus.$emit("someEvent", 'Data to send')
Enter fullscreen mode Exit fullscreen mode

ComponentB.js

mounted() {
this.$bus.$on("someEvent", (data) => {
    console.log(data);
    //Some stuff to do..
}
Enter fullscreen mode Exit fullscreen mode

That’s pretty neat and clean. Thank you for reading!

Top comments (5)

Collapse
 
duboiss profile image
Steven

For this usage we can have the same benefits without mitt, native Nuxt 3 only.
useNuxtApp().callHook("cart:flush", "test")

useNuxtApp().hooks.hook('cart:flush', (message: string) => console.log(message));

Collapse
 
riyaz7us profile image
riyaz7us

It works. I created the plugin as follows (using setup):

import mitt from "mitt";
const emitter = mitt();
export default defineNuxtPlugin({
  setup(nuxtApp) {
    return {
      provide: { bus: { $on: emitter.on, $emit: emitter.emit } },
    };
  },
});
Enter fullscreen mode Exit fullscreen mode

Then I used it like this:

  useNuxtApp().$bus.$on("myEv",(e)=>{
    //whatever
  });
Enter fullscreen mode Exit fullscreen mode
Collapse
 
twitapp7 profile image
twitapp

It's not working for me.

I see that the plugin is loaded, with a console.log line.

However, this.$bus remains undef... most of the time.

I was playing around with when to call the $emit and $on functions, between mounted and created on a component and layout object, and sometimes it would work, but only temporarily, until I reloaded the page, then it would always break.

So my guess is that I'm misunderstanding something about when $bus will become available.

Collapse
 
jordashtalon profile image
Jordan • Edited

I had the same problem in order to fix you need to define bus at the top of script setup like this:

<script setup>
const {$bus} = useNuxtApp();
</script>

Collapse
 
nicknotararigo profile image
Nicolas Notararigo

It's working for me, i rename this files : mitt.client.js in mitt.js and i declare it in my nuxt.config.ts