8
votes

Vue.js 3 Event Bus

Comment créer un bus d'événements dans Vue 3?


Dans Vue 2, c'était:

bus.$on(...)
bus.$emit(...)
export const bus = new Vue();

Dans Vue 3, Vue n'est plus un constructeur, et Vue.createApp({}); renvoie un objet qui n'a pas $on méthodes $on et $emit .


3 commentaires

La RFC suggère d'utiliser une bibliothèque tierce à la place: github.com/vuejs/rfcs/blob/master/active-rfcs / ...


Pouvez-vous développer les fonctionnalités dont vous avez besoin? Dans certains cas, même un ref fonctionnerait.


Pour avoir un objet partagé pour tous les composants afin d'émettre et d'écouter des événements dessus. (C'est à cela que sert le bus d'événements.)


3 Réponses :


-5
votes

Dans un projet Vuejs, vous pouvez créer un nouveau fichier sur la même racine que App.vue et instancier le constructeur Vue.

fichier eventBus.js

EventBus.$emit("evMsg", someData);
EventBus.$on("evMsg", (someData) => {});

Ensuite, il vous suffit d'importer l'événement sur chaque fichier vue que vous souhaitez émettre ou recevoir l'événement, comme ceci:

import EventBus from "../eventBus.js";

Pour simplement émettre et recevoir l'événement, utilisez le $ emit / $ on mark

import Vue from 'vue';
export default new Vue();


4 commentaires

Cette rubrique concerne Vue 3. De plus, j'ai écrit le court exemple dans le message de rubrique comment créer le bus d'événements dans Vue 2.


J'utilise Vue 3 avec cette approche.


Je ne pense pas que vous l'êtes - $ on a été supprimé: v3.vuejs.org/guide/migration/events-api.html#overview


Réponse incorrecte car. $ On et. $ Emit ont été supprimés dans VUE3



10
votes

Comme suggéré dans la documentation officielle, vous pouvez utiliser la bibliothèque mitt pour répartir les événements entre les composants, supposons que nous ayons une barre latérale et un en-tête contenant un bouton qui ferme / ouvre la barre latérale et nous avons besoin de ce bouton pour basculer une propriété à l'intérieur du composant de la barre latérale:

dans main.js importez cette bibliothèque et créez une instance de cet émetteur et définissez-la comme propriété globale :

Installation:

import { getCurrentInstance } from 'vue'
export default{

   setup(){
      const internalInstance = getCurrentInstance(); 
      const emitter = internalInstance.appContext.config.globalProperties.emitter;

       ...
     },
  ...

}

Utilisation:

<template>
  <aside class="sidebar" :class="{'sidebar--toggled':!isOpen}">
  ....
  </aside>
</template>
<script>
export default {
  name: "sidebar",
  data() {
    return {
      isOpen: true
    };
  },
  mounted() { 
    this.emitter.on("toggle-sidebar", isOpen => {
      this.isOpen = isOpen;
    });
  }
};
</script>

dans l'en-tête, émet l'événement toggle-sidebar avec une charge utile:

<template>
  <header>
    <button  @click="toggleSidebar"/>toggle</button>
  </header>
</template>
<script >
export default { 
  data() {
    return {
      sidebarOpen: true
    };
  },
  methods: {
    toggleSidebar() {
      this.sidebarOpen = !this.sidebarOpen;
      this.emitter.emit("toggle-sidebar", this.sidebarOpen);
    }
  }
};
</script>

Dans la barre latérale, recevez l'événement avec la charge utile:

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt';
const emitter = mitt();
let app=createApp(App)
app.config.globalProperties.emitter = emitter
app.mount('#app')

Pour ceux qui utilisent l'API de composition, ils peuvent utiliser l' emitter comme suit:

 npm install --save mitt


2 commentaires

pour ceux qui utilisent l'API de composition, vous pouvez obtenir l'émetteur avec const internalInstance = getCurrentInstance(); const emitter = internalInstance.appContext.config.globalProperties.emitter; (il faut d' getCurrentInstance importer getCurrentInstance depuis vue ). src: v3.vuejs.org/api/composition-api.html#getcurrentinstance


merci pour cette note, j'ai ajouté cela à ma réponse



6
votes

Dans la version 3 de Vue.js, vous pouvez utiliser une bibliothèque tierce ou utiliser la fonctionnalité écrite dans le modèle de programmation éditeur-abonné (concept PubSub).

event.js

import Vue from 'vue';
import $bus from '.../event.js';

const app = Vue.createApp({})
app.config.globalProperties.$bus = $bus;

index.js

//events - a super-basic Javascript (publish subscribe) pattern

class Event{
    constructor(){
        this.events = {};
    }

    on(eventName, fn) {
        this.events[eventName] = this.events[eventName] || [];
        this.events[eventName].push(fn);
    }

    off(eventName, fn) {
        if (this.events[eventName]) {
            for (var i = 0; i < this.events[eventName].length; i++) {
                if (this.events[eventName][i] === fn) {
                    this.events[eventName].splice(i, 1);
                    break;
                }
            };
        }
    }

    trigger(eventName, data) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(function(fn) {
                fn(data);
            });
        }
    }
}

export default new Event();


0 commentaires