Vue3中事件总线的具体使用

 更新时间:2023年04月11日 14:28:57   作者:zerotower  
本文主要介绍了Vue3中事件总线的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

导读

在Vue2中,我们遇到复杂的组件通信时,经常采用事件总线的方式来通信。其具体的思路就是实例化一个空白的Vue,并通过其提供的$on$once$emit方法来进行通信。而在Vue3中,上述三个API已经被移除了,那么我们又如何使用事件总线呢?

事件总线的本质

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实例化并全局引入

上文已经说了有两种引入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
<script setup>
import {getCurrentInstance} from "vue"
const vm=getCurrentInstance();
vm.proxy.$event.on('test',()=>{
    console.log('test event emit!')
})
</script>

//Comp2
<script setup>
import {getCurrentInstance} from "vue"
const vm=getCurrentInstance();
vm.proxy.$event.emit('test',"a","b")
</script>

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

provide/inject

在main.js中

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

在组件中

//Comp1
<script setup>
import {inject} from "vue";
const bus1=inject("eventBus1")
bus1.on("bus1-on-event",()=>{
    console.log('eventBus1 on event emit!')
})
</script>
//Comp2
<script setup>
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")
</script>
//Comp3
<script setup>
import {inject} from "vue";
const bus2=inject("eventBus2")
bus2.emit("bus2-on-event")
</script>

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

结束语

到此这篇关于Vue3中事件总线的具体使用的文章就介绍到这了,更多相关Vue3 事件总线内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在Vue里如何把网页的数据导出到Excel的方法

    在Vue里如何把网页的数据导出到Excel的方法

    这篇文章主要介绍了在Vue里如何把网页的数据导出到Excel,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • vue全局数据管理示例详解

    vue全局数据管理示例详解

    这篇文章主要为大家介绍了vue全局数据管理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 解决Vue.js Devtools未检测到Vue实例的问题

    解决Vue.js Devtools未检测到Vue实例的问题

    在开发Vue.js应用时,Vue.js Devtools是一个不可或缺的调试工具,然而,有时我们可能会遇到“Vue.js not detected”的提示,这意味着Vue.js Devtools未能成功识别和连接到我们的Vue应用,本文将详细解析这个问题,并提供相应的解决步骤与代码示例,需要的朋友可以参考下
    2024-01-01
  • vue路由传参的基本实现方式小结【三种方式】

    vue路由传参的基本实现方式小结【三种方式】

    这篇文章主要介绍了vue路由传参的基本实现方式,结合实例形式总结分析了vue.js路由传参的三种实现方式,包括params显示传参、不显示参数以及query显示参数传参,需要的朋友可以参考下
    2020-02-02
  • 关于在vue 中使用百度ueEditor编辑器的方法实例代码

    关于在vue 中使用百度ueEditor编辑器的方法实例代码

    这篇文章主要介绍了在vue 中使用百度ueEditor编辑器的方法实例代码 ,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • vue 更改连接后台的api示例

    vue 更改连接后台的api示例

    今天小编就为大家分享一篇vue 更改连接后台的api示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue中render函数的使用方法

    Vue中render函数的使用方法

    本篇文章主要介绍了Vue中render函数的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 详解vue2.0+axios+mock+axios-mock+adapter实现登陆

    详解vue2.0+axios+mock+axios-mock+adapter实现登陆

    这篇文章主要介绍了详解vue2.0+axios+mock+axios-mock+adapter实现登陆,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • element表格翻页第2页从1开始编号(后端从0开始分页)

    element表格翻页第2页从1开始编号(后端从0开始分页)

    这篇文章主要介绍了element表格翻页第2页从1开始编号(后端从0开始分页),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Vue中使用Element UI的Table组件实现嵌套表格功能

    Vue中使用Element UI的Table组件实现嵌套表格功能

    这篇文章主要介绍了Vue中使用Element UI的Table组件实现嵌套表格功能,演示如何在Vue中使用Element UI的Table组件实现嵌套表格,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01

最新评论