溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue3中的事件總線怎么使用

發(fā)布時(shí)間:2023-04-11 15:34:50 來(lái)源:億速云 閱讀:143 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“Vue3中的事件總線怎么使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

事件總線的本質(zhì)

Vue2中的$on、$once、$emit本質(zhì)上就是其內(nèi)部實(shí)現(xiàn)了一個(gè)EventEmitter(事件派發(fā)器),每一個(gè)事件都和若干回調(diào)相對(duì)應(yīng),只要事件被觸發(fā),那么就將執(zhí)行此事件所有對(duì)應(yīng)的回調(diào)。同時(shí),在JavaScript中,該思想被廣泛地使用,尤其在Node.js的事件機(jī)制中,就是創(chuàng)建了一個(gè)EventEmitter實(shí)例,具體請(qǐng)自行查閱相關(guān)資料。因此,我們只需要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的EventEmitter,并全局傳遞到每一個(gè)組件中,就可以實(shí)現(xiàn)一個(gè)事件總線了。而全局傳遞,我們可以使用config.globalProperties綁定到每一個(gè)組件,也可以在根組件(main)中,通過(guò)provide提供總線,需要使用的組件使用inject注入。下面就讓我們來(lái)實(shí)現(xiàn)一下吧。

構(gòu)建一個(gè)EventEmitter

由于我們可能會(huì)有多條總線,我們還是把EventEmitter寫(xiě)成類的方式,每一條總線都將是一個(gè)EventEmitter實(shí)例。以下是EventEmitter的簡(jiǎn)單實(shí)現(xiàn),其只實(shí)現(xiàn)了on、onceemit三個(gè)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實(shí)例化并全局引入

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>

但這種方法不太優(yōu)雅,不方便定義多條總線,建議使用下述的方法。

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更優(yōu)雅一些,且不使用就不必使用inject注入。

“Vue3中的事件總線怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI