Maison  >  Questions et réponses  >  le corps du texte

Bus d'événements Vue.js 3

<p>Comment créer un bus d'événements dans Vue 3 ? </p> <heure /> <p>Dans Vue 2, c'est : </p> <pre class="brush:js;toolbar:false;">export const bus = new Vue(); ≪/pré> <pre class="brush:js;toolbar:false;">bus.$on(...) bus.$emit(...) ≪/pré> <heure /> <p>Dans Vue 3, <code>Vue</code> n'est plus un constructeur, et <code>Vue.createApp({});</code> renvoie un sans <code>$ on< ;/code> code objet> et <code>$emit</code> </p>
P粉905144514P粉905144514422 Il y a quelques jours438

répondre à tous(2)je répondrai

  • P粉638343995

    P粉6383439952023-08-25 16:53:26

    Sur Vue.js version 3, vous pouvez utiliser des bibliothèques tierces ou des fonctions écrites dans le modèle de programmation éditeur-abonné (concept PubSub).

    événement.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();
    

    index.js

    import Vue from 'vue';
    import $bus from '.../event.js';
    
    const app = Vue.createApp({})
    app.config.globalProperties.$bus = $bus;
    

    répondre
    0
  • P粉744831602

    P粉7448316022023-08-25 00:55:58

    Comme suggéré dans la documentation officielle, vous pouvez utiliser la bibliothèque mitt pour répartir les événements entre les composants, en supposant que nous ayons une barre latérale et un header< /code> qui contient un bouton pour fermer/ouvrir la barre latérale, nous avons besoin de ce bouton pour basculez certaines propriétés dans le composant de la barre latérale : 

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

    Installation :

    npm install --save mitt
    

    Utilisation :

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

    Émettez un événement toggle-sidebartoggle-sidebar avec une charge utile dans l'en-tête :

    <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>
    

    Recevoir des événements avec la charge utile dans la barre latérale :

    <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>
    

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

    Créer le fichier src/composables/useEmitter.js

    import { getCurrentInstance } from 'vue'
    
    export default function useEmitter() {
        const internalInstance = getCurrentInstance(); 
        const emitter = internalInstance.appContext.config.globalProperties.emitter;
    
        return emitter;
    }
    
    

    À partir de là, vous pouvez utiliser useEmitter,就像使用 useRouteruseEmitter comme vous le feriez avec

    useRouter :

    import useEmitter from '@/composables/useEmitter'
    
    export default {
      setup() {
        const emitter = useEmitter()
        ...
      }
      ...
    }
    
    Utiliser l'API combinée

    Vous pouvez également bénéficier de la nouvelle API de composition et définir des bus événementiels composables :

    eventBus.js

    import { ref } from "vue";
    const bus = ref(new Map());
    
    export default function useEventsBus(){
    
        function emit(event, ...args) {
            bus.value.set(event, args);
        }
    
        return {
            emit,
            bus
        }
    }
    

    Faites ce qui suit dans le composant A :

    import useEventsBus from './eventBus';
    ...
    //in script setup or inside the setup hook
    const {emit}=useEventsBus()
    ...
     emit('sidebarCollapsed',val)
    
    

    Dans le composant B : 🎜
    const { bus } = useEventsBus()
    
    watch(()=>bus.value.get('sidebarCollapsed'), (val) => {
      // destruct the parameters
        const [sidebarCollapsedBus] = val ?? []
        sidebarCollapsed.value = sidebarCollapsedBus
    })
    
    

    répondre
    0
  • Annulerrépondre