Global event bus in VueJS

Vediamo insieme come creare un global event bus in VueJS

Utilizzando il pattern event-bus / pub-sub possiamo mettere in comunicazione parti della nostra applicazione che normalmente sarebbero separate. Un caso molto comune lo ritroviamo nelle modali: abbiamo un pulsante all'interno della pagina che tramite l'emissione di un evento apre una modale definita in un altro punto. Esistono diverse librerie che implementano questo pattern ma in VueJS possiamo utilizzarlo senza ulteriori strumenti esterni.

# Configurazione

La prima cosa da fare per utilizzare un global event bus in VueJS è creare un'istanza separata di Vue ed esportarla. In questo modo possiamo andare ad importare quest'istanza in tutte le parti dell'applicazione dove abbiamo la necessità di usare un global event bus.

// global-event-bus.js

import Vue from "vue"

export const EventBus = new Vue()

# Emettere gli eventi

Per emettere degli eventi sul global event bus ci basterà importare l'istanza comune che abbiamo creato e richiamare il metodo $emit su quest'ultima:

<template>
  <button @click="onButtonClick">Click me</button>
</template>

<script>
  import { EventBus } from "@/global-event-bus.js"

  export default {
    data() {
      return {
        count: 0
      }
    },
    methods: {
      onButtonClick() {
        this.count++
        EventBus.$emit("button-clicked", this.count)
      }
    }
  }
</script>

# Ricevere gli eventi

Anche in questo caso ci basterà importare l'istanza del global event bus e richiamare il metodo $on:

import { EventBus } from "@/global-event-bus.js"

const clickHandler = (count) => console.log(`Button clicked ${count} times!`)

EventBus.$on("button-clicked", clickHandler)

// Riceviamo l'evento solo una volta
EventBus.$once("button-clicked", clickHandler)

// Smettiamo di ricevere eventi
EventBus.$off("button-clicked", clickHandler)

Se vogliamo ricevere l'evento solo una volta possiamo utilizzare il metodo $once, mentre se non vogliamo più ricevere eventi possiamo utilizzare il metodo $off.