Vue.js 3 Event Bus

前端 未结 3 2044
粉色の甜心
粉色の甜心 2020-12-10 05:52

How to create Event Bus in Vue 3?


In Vue 2, it was:

export const bus = new Vue();


        
相关标签:
3条回答
  • 2020-12-10 06:07

    On version 3 of Vue.js, you can use either a third-party library, or use the functionality written in the publisher-subscriber(PubSub concept) programming pattern.

    event.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;
    
    0 讨论(0)
  • 2020-12-10 06:08

    In a Vuejs project you can create a new file on the same root as App.vue and instanciate the Vue constructor.

    eventBus.js file

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

    Then, you only have to import the event on every vue file you want to emit or receiving the event, like this:

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

    To just emit and receive the event use the $emit/$on mark

    EventBus.$emit("evMsg", someData);
    EventBus.$on("evMsg", (someData) => {});
    
    0 讨论(0)
  • 2020-12-10 06:24

    As suggested in official docs you could use mitt library to dispatch events between components, let suppose that we a sidebar and header which contains a button that close/open the sidebar and we need that button to toggle some property inside the sidebar component :

    in main.js import that library and create an instance of that emitter and define as a global property:

    Installation :

     npm install --save mitt
    

    Usage :

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

    in header emit the toggle-sidebar event with some payload :

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

    In sidebar receive the event with the payload:

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

    For those using composition api they could use emitter as follows :

    import { getCurrentInstance } from 'vue'
    export default{
    
       setup(){
          const internalInstance = getCurrentInstance(); 
          const emitter = internalInstance.appContext.config.globalProperties.emitter;
    
           ...
         },
      ...
    
    }
    
    
    0 讨论(0)
提交回复
热议问题