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 Réponses :
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();
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
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
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
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();
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.)