Vue3中事件總線mitt的使用方式
我的使用場景
在項目中遇到一個這樣的問題。頁面使用了keepalive緩存, 員工排班和班次之間的數(shù)據(jù)有關(guān)聯(lián),當我刪除一個班次后,給員工排的班,屬于那個被刪的班次的情況,已經(jīng)生效的不會受影響,但是未生效的排班會被刪除。如果我不重新拉取后端數(shù)據(jù)的話,我從班次頁面切換到員工排班頁面,我前端的排班還是存在的,但是后端的數(shù)據(jù)已經(jīng)刪除了。這個時候用戶點擊刪除排班,就會出現(xiàn)不友好的提示,我需要避免這個情況。這就需要再刪除班次的時候,重新拉取員工排班列表的數(shù)據(jù)了。
使用方法
安裝mitt
npm install mitt
創(chuàng)建一個事件總線
在你的項目中創(chuàng)建一個事件總線,可以將其放在一個單獨的文件中,例如 eventBus.js
// eventBus.js import mitt from 'mitt'; export const eventBus = mitt();
在員工排班中監(jiān)聽事件
監(jiān)聽來自事件總線的事件,然后調(diào)用相應的方法,記得要在頁面銷毀的時候,取消監(jiān)聽。
// schedule.vue import { ref, onMounted, onBeforeUnmount } from 'vue'; import { eventBus } from '@/path/to/eventBus'; // 這個路徑需要對應上 export default { setup() { const search = () => { // 在這里執(zhí)行方法 console.log('方法被調(diào)用'); }; onMounted(() => { eventBus.on('getScheduleSearch', search); }); // 在頁面被銷毀的時候,取消監(jiān)聽 onBeforeUnmount(() => { eventBus.off('getScheduleSearch', search); }); return {}; }, };
在班次頁面中觸發(fā)事件
觸發(fā)事件,通知員工排班頁面執(zhí)行方法。
// shift.vue import { ref } from 'vue'; import { eventBus } from '@/path/to/eventBus'; // 這個路徑需要對應上 export default { setup() { // 假設這是我刪除班次的方法 const deleteShift = () => { // 在這里觸發(fā)事件,通知員工排班頁面執(zhí)行方法。 eventBus.emit('getScheduleSearch'); }; return { getScheduleSearch }; }, };
這樣,你就可以在班次頁面中調(diào)用 deleteShift 方法時,員工排班頁面中的 search 方法就會被觸發(fā)。這是一種基于事件的簡單而靈活的通信方式,適用于不同組件之間的解耦。
延展:vue3 mitt進行兄弟組件通信
mitt又稱事務總線,是第三方插件。
Vue2.x 使用 EventBus 進行組件通信,而 Vue3.x 推薦使用 mitt.js。
優(yōu)點
首先它足夠小,僅有200bytes,其次支持全部事件的監(jiān)聽和批量移除,它還不依賴 Vue 實例,所以可以跨框架使用,React 或者 Vue,甚至 jQuery 項目都能使用同一套庫。
下載
npm install --save mitt
引入
方式1:main.js全局總線
import { createApp } from 'vue'; import App from './App.vue'; import mitt from "mitt" const app = createApp(App) app.config.globalProperties.$mybus = mitt()
方式2:單獨定義mybus.js文件,想用的時候再導入
//mybus.js文件 import mitt from 'mitt' const emitter = mitt(); export default emitter ;
方式3:直接在組件導入
import mitt from 'mitt' setup(){ const emitter = mitt(); return{ emitter } }
使用
//使用 import emitter from '@/utils/mybus.js'; //發(fā)送 emitter.emit('getDetail',{name:'張三',age:20}); //監(jiān)聽 emitter.on("getDetail",(val) = >{ console.log(val) }) //取消監(jiān)聽 emitter.off("getDetail") //如果發(fā)送了多個,可監(jiān)聽全部 emitter.on("*",(type,val) = >{ console.log(type,val) //type就是類型 之前注冊的getDetail }) //取消所有監(jiān)聽 emitter.all.clear();
核心原理
Vue3.x以后從實例中移除了 $on
,$off
和 $once
方法,$emit
仍然是現(xiàn)有 API 的一部分,只能實現(xiàn)子組件觸發(fā)父組件的方法。
原理很簡單,就是通過 map 的方法保存函數(shù)。
export default function mitt(all) { all = all || new Map(); return { all, on(type, handler) { const handlers = all.get(type); const added = handlers && handlers.push(handler); if (!added) { all.set(type, [handler]); } }, off(type, handler) { const handlers = all.get(type); if (handlers) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); } }, emit(type, evt) { ((all.get(type) || [])).slice().map((handler) => { handler(evt); }); ((all.get('*') || [])).slice().map((handler) => { handler(type, evt); }); } }; }
到此這篇關(guān)于Vue3中事件總線mitt的使用方式的文章就介紹到這了,更多相關(guān)Vue3 事件總線mitt內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!