Bus d'événements Vue.js 3
P粉905144514
P粉905144514 2023-08-24 18:08:45
0
2
502
<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粉905144514
P粉905144514

répondre à tous(2)
P粉638343995

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;
P粉744831602

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

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal