Vue3 數(shù)據(jù)總線的實(shí)現(xiàn)
在 Vue 開(kāi)發(fā)中,組件通信 是一個(gè)非常重要的主題。對(duì)于父子組件之間的通信,我們可以通過(guò) props/emit 來(lái)實(shí)現(xiàn)。然而,在 非父子組件 或 兄弟組件 之間進(jìn)行通信時(shí),傳統(tǒng)的 props/emit 就顯得力不從心了。這時(shí),事件總線(Event Bus) 就派上了用場(chǎng)。
在 Vue 2 中,我們可以通過(guò) new Vue() 創(chuàng)建一個(gè)事件總線實(shí)例,并使用 $emit、$on 和 $off 來(lái)實(shí)現(xiàn)事件的發(fā)布與訂閱。然而,在 Vue 3 中,這些 API 被移除了。幸運(yùn)的是,我們可以借助一個(gè)輕量級(jí)的開(kāi)源庫(kù) —— mitt 來(lái)實(shí)現(xiàn)類似的功能。
什么是mitt?
mitt 是一個(gè)極簡(jiǎn)的JavaScript事件發(fā)布/訂閱庫(kù),體積僅有200字節(jié)左右,但卻功能強(qiáng)大。它可以在任何 JavaScript 環(huán)境中使用,包括 Vue、React 甚至原生 JS。mitt 的核心功能非常簡(jiǎn)單:
- 發(fā)布事件:通過(guò)
emit方法觸發(fā)事件。 - 訂閱事件:通過(guò)
on方法監(jiān)聽(tīng)事件。 - 取消訂閱:通過(guò)
off方法移除事件監(jiān)聽(tīng)器。
如何在 Vue 3 中使用mitt?
1、安裝mitt
首先,我們需要通過(guò) npm 安裝 mitt:
npm i mitt
2、創(chuàng)建事件總線
接下來(lái),我們創(chuàng)建一個(gè)事件總線實(shí)例
import mitt from "mitt"; const emitter = mitt(); export default emitter;
3、在組件中訂閱事件
<template>
<div>
<div>Bar: {{ date }}</div>
</div>
</template>
<script setup lang="ts">
import { onBeforeMount, onMounted, ref } from 'vue';
import emitter from './emitter';
const date = ref()
onMounted(() => {
emitter.on('bar', (data) => {
date.value = data
})
})
onBeforeMount(() => {
emitter.off('bar')
})
</script>
4、在組件中發(fā)布事件
// Foo.vue
<template>
<div>
<span>Foo: </span>
<button @click="click">觸發(fā)事件</button>
</div>
</template>
<script setup lang="ts">
import emitter from './emitter';
function click() {
emitter.emit('bar', new Date().toLocaleString());
}
</script>
mitt實(shí)現(xiàn)原理
miit的原理其實(shí)非常簡(jiǎn)單,主要依賴于一個(gè) Map 對(duì)象來(lái)存儲(chǔ)事件類型及其對(duì)應(yīng)的處理函數(shù)。以下是mitt的簡(jiǎn)化實(shí)現(xiàn):
function mitt() {
const all = new Map();
return {
// 訂閱事件
on(type, handler) {
const handlers = all.get(type)
if (handlers) {
handlers.push(handler)
} else {
all.set(type, [handler])
}
},
// 取消訂閱
off(type, handler) {
const handlers = all.get(type)
if (!handlers) {
return
}
if (handler) {
const index = handlers.indexOf(handler)
if (index > -1) {
handlers.splice(index, 1)
}
} else {
all.set(type, [])
}
},
// 發(fā)布事件
emit(type, ...args) {
const handlers = all.get(type);
handlers?.slice().map(handler => {
handler(...args)
})
}
}
}
到此這篇關(guān)于Vue3 數(shù)據(jù)總線的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3 數(shù)據(jù)總線內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ant Design Vue table中列超長(zhǎng)顯示...并加提示語(yǔ)的實(shí)例
這篇文章主要介紹了Ant Design Vue table中列超長(zhǎng)顯示...并加提示語(yǔ)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
Vue3實(shí)現(xiàn)計(jì)算屬性的代碼詳解
計(jì)算屬性對(duì)于前端開(kāi)發(fā)來(lái)說(shuō)算是經(jīng)常使用的一個(gè)能力了,本文將從代碼層面來(lái)給大家介紹下Vue3是如何實(shí)現(xiàn)計(jì)算屬性的,需要的朋友可以參考下2023-07-07
Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件
這篇文章主要介紹了Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
詳解vue3自定義指令實(shí)現(xiàn)?v-focus?功能
在Vue3中,可以通過(guò)自定義指令來(lái)實(shí)現(xiàn)v-focus功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-05-05
element-ui?form表單的動(dòng)態(tài)rules校驗(yàn)功能實(shí)現(xiàn)
在vue項(xiàng)目中,有時(shí)候可能會(huì)用到element-ui?form表單的動(dòng)態(tài)rules校驗(yàn),這篇文章主要介紹了element-ui form表單的動(dòng)態(tài)rules校驗(yàn),我們可以巧妙的運(yùn)用element-ui form表單里面form-item的校驗(yàn)規(guī)則來(lái)處理,本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
el-input輸入校驗(yàn)不能為空格以及不能輸入全部為空的內(nèi)容
這篇文章主要給大家介紹了關(guān)于el-input輸入校驗(yàn)不能為空格以及不能輸入全部為空的內(nèi)容的相關(guān)資料,el-input驗(yàn)證規(guī)則主要是為了確保輸入的內(nèi)容符合特定的要求,需要的朋友可以參考下2023-10-10

