How to use Emit in Nuxt 3

Using emit / emitter / mitt in Nuxt 3 can be quite hard

Nuxt.js is a popular open-source framework for building Vue.js applications. It provides features such as server-side rendering and generating static websites, making it a powerful tool for web development. One of the features you might use frequently in Nuxt.js is the event emitting feature. In Nuxt.js, as with Vue.js, an "emit" function is used to create custom events. This is especially useful when you want child components to communicate with their parent components, typically by sending data. However, there might be scenarios where you need to emit events globally across your application. This is where a global event becomes handy.
Understanding Global Events A global event is an event that is emitted from a component and can be captured by any other component within your application. Generally, you emit events from a child component and capture them from its parent. For instance, you may have a `NavBar.vue` component with a login button that's part of the application template. Additionally, you might have multiple pages where one of them contains dynamic data based on whether a user is logged in or not. The tricky part is that the `NavBar.vue` component isn't included in the `Page.vue` views, so you can't use the default `$emit`. Moreover, since the `NavBar.vue` component is part of the application layout, users can log in from any page after the `Page.vue` view has been loaded, meaning you can't just check if the user is logged in on the `mounted` or `created` hooks. This is an excellent scenario to employ global events.
What is an Emitter? An event emitter is a pattern that listens to a named event, triggers a callback function, and then emits that event with a value. This pattern is often referred to as the "pub/sub" model or listener. It enables different parts of your application to communicate with each other effectively and ensures loose coupling between components, enhancing code maintainability.
Using Emit in Nuxt: Solution 1 Let's explore how you can use emit in Nuxt.js. Here's a general overview of how it's done: Firstly, you need to initialize an instance of NuxtApp in your `index.vue`:
javascript
<script lang="ts" setup> 
const { $bus } = useNuxtApp() 
</script>
Install Mitt package manager trough npm install --save mitt (https://www.npmjs.com/package/mitt) Make a folder and call it "plugins" I made the folder under the generated "plugins" folder. Make an emitter.js file in the plugins folder and add this code :
import { defineNuxtPlugin } from '#app'
import mitt from 'mitt'
const emitter = mitt()

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.provide('bus', {
    $on: emitter.on,
    $emit: emitter.emit,
  })
})

Here, `$bus` acts as a channel for transmitting events across your application. You can think of `$bus` as a bus carrying messages (events) from one point to another. Next, consider this code snippet from `default.vue`:
<script lang="ts">
export default { 
  data(){
    return{
      myVar: ''
    }
  },
  mounted: function() {
    this.myVar = 1;
  }
}
</script>
This code initializes `myVar` in the data property of the component, which is then assigned the value of the current hostname when the component is mounted. You can use `$bus.$emit` to emit an event globally. Here's an example of how to do this in a button click handler:
<a @click="$bus.$emit('openOffer', {'foo': 'bar'})">Click Me</a>
In this case, when the button is clicked, the 'openOffer' event is emitted globally, carrying along a data object `{'foo': 'bar'}`. Finally, consider the following code snippet from a hypothetical `Component.vue`:
export default {
  methods: {
    openModal(data: any) {
      // ... (code to open modal)
    },
    clickEvent

(data: any) {
      console.log('Emitter received', data);
    },
  },
  created() {
    const { $bus }: any = this;
    $bus.$on('clickEvent', this.clickEvent);
    $bus.$on('openOffer', this.openModal);
  },
  beforeDestroy() {
    const { $bus }: any = this;
    $bus.$off('clickEvent', this.clickEvent);
    $bus.$off('openOffer', this.openModal);
  }
};
In the `created()` lifecycle hook, we set up listeners for the 'clickEvent' and 'openOffer' events. Whenever these events are emitted globally, the corresponding handler (`clickEvent` or `openModal`) will be triggered. To prevent memory leaks, it's important to remove these listeners when the component is destroyed, which is done in the `beforeDestroy()` lifecycle hook. Hopefully, this guide gives you a better understanding of how to use emit in Nuxt.js effectively to manage global events. Happy coding!
by Daniel at 2023-06-23T08:56:36.162Z
Copyright © DanielKnows.com 2019 - 2023 - Built with NuxtJS