验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

Vue3中的事件总线怎么使用

阅读:1095 来源:乙速云 作者:代码code

Vue3中的事件总线怎么使用

事件总线的本质

Vue2中的$on$once$emit本质上就是其内部实现了一个EventEmitter(事件派发器),每一个事件都和若干回调相对应,只要事件被触发,那么就将执行此事件所有对应的回调。同时,在JavaScript中,该思想被广泛地使用,尤其在Node.js的事件机制中,就是创建了一个EventEmitter实例,具体请自行查阅相关资料。因此,我们只需要实现一个简单的EventEmitter,并全局传递到每一个组件中,就可以实现一个事件总线了。而全局传递,我们可以使用config.globalProperties绑定到每一个组件,也可以在根组件(main)中,通过provide提供总线,需要使用的组件使用inject注入。下面就让我们来实现一下吧。

构建一个EventEmitter

由于我们可能会有多条总线,我们还是把EventEmitter写成类的方式,每一条总线都将是一个EventEmitter实例。以下是EventEmitter的简单实现,其只实现了ononceemit三个API。

class EventEmitter{
    constructor(){
        this.callbacks={};
    }
    on(envetName,callback){
        if(!Array.isArray(this.callbacks[envetName])){
            this.callbacks[envetName]=[];
        }
        this.callbacks[envetName].push(callback);
    }
    emit(eventName,...args){
        if(Array.isArray(this.callbacks[eventName])){
            this.callbacks[eventName].forEach(callback=>callback(...args));
        }
    }
    off(eventName,callback){
        if(!Array.isArray(this.callbacks[eventName])){
            return
        }
        if(callback){
            this.callbacks[eventName].forEach(cb=>{
                if(callback===cb){
                    this.callbacks[eventName].splice(this.callbacks[eventName].indexOf(callback),1);
                }
            });
        } else{
            this.callbacks[eventName]=[];
        }
    }
    once(eventName,callback){
        const that=this;
        const fn=function(){
            callback.apply(that,[...arguments]);
            that.off(eventName,fn);
        }
        that.on(eventName,fn);
    }
}

将EventEmitter实例化并全局引入

config.globalProperties方法

在main.js中

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
const app=createApp(App);
app.config.globalProperties.$event=new EventEmitter();
app.mount('#app')

在组件中:

//Comp1

import {getCurrentInstance} from "vue"
const vm=getCurrentInstance();
vm.proxy.$event.on('test',()=>{
    console.log('test event emit!')
})


//Comp2

import {getCurrentInstance} from "vue"
const vm=getCurrentInstance();
vm.proxy.$event.emit('test',"a","b")

但这种方法不太优雅,不方便定义多条总线,建议使用下述的方法。

provide/inject

在main.js中

provide("eventBus1",new EventEmitter());
provide("eventBus2",new EventEmitter());

在组件中

//Comp1

import {inject} from "vue";
const bus1=inject("eventBus1")
bus1.on("bus1-on-event",()=>{
    console.log('eventBus1 on event emit!')
})

//Comp2

import {inject} from "vue";
const bus1=inject("eventBus1")
const bus2=inject("eventBus2")
bus2.on("bus2-on-event",()=>{
    console.log('eventBus2 on event emit!')
})
bus1.emit("bus1-on-event")

//Comp3

import {inject} from "vue";
const bus2=inject("eventBus2")
bus2.emit("bus2-on-event")

此方法中,使用inject也比使用getCurrentInstance.proxy更优雅一些,且不使用就不必使用inject注入。

分享到:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>