Vue3中事件总线mitt的使用方式
作者:又蓝
我的使用场景
在项目中遇到一个这样的问题。页面使用了keepalive缓存, 员工排班和班次之间的数据有关联,当我删除一个班次后,给员工排的班,属于那个被删的班次的情况,已经生效的不会受影响,但是未生效的排班会被删除。如果我不重新拉取后端数据的话,我从班次页面切换到员工排班页面,我前端的排班还是存在的,但是后端的数据已经删除了。这个时候用户点击删除排班,就会出现不友好的提示,我需要避免这个情况。这就需要再删除班次的时候,重新拉取员工排班列表的数据了。
使用方法
安装mitt
npm install mitt
创建一个事件总线
在你的项目中创建一个事件总线,可以将其放在一个单独的文件中,例如 eventBus.js
// eventBus.js import mitt from 'mitt'; export const eventBus = mitt();
在员工排班中监听事件
监听来自事件总线的事件,然后调用相应的方法,记得要在页面销毁的时候,取消监听。
// schedule.vue import { ref, onMounted, onBeforeUnmount } from 'vue'; import { eventBus } from '@/path/to/eventBus'; // 这个路径需要对应上 export default { setup() { const search = () => { // 在这里执行方法 console.log('方法被调用'); }; onMounted(() => { eventBus.on('getScheduleSearch', search); }); // 在页面被销毁的时候,取消监听 onBeforeUnmount(() => { eventBus.off('getScheduleSearch', search); }); return {}; }, };
在班次页面中触发事件
触发事件,通知员工排班页面执行方法。
// shift.vue import { ref } from 'vue'; import { eventBus } from '@/path/to/eventBus'; // 这个路径需要对应上 export default { setup() { // 假设这是我删除班次的方法 const deleteShift = () => { // 在这里触发事件,通知员工排班页面执行方法。 eventBus.emit('getScheduleSearch'); }; return { getScheduleSearch }; }, };
这样,你就可以在班次页面中调用 deleteShift 方法时,员工排班页面中的 search 方法就会被触发。这是一种基于事件的简单而灵活的通信方式,适用于不同组件之间的解耦。
延展:vue3 mitt进行兄弟组件通信
mitt又称事务总线,是第三方插件。
Vue2.x 使用 EventBus 进行组件通信,而 Vue3.x 推荐使用 mitt.js。
优点
首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖 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'; //发送 emitter.emit('getDetail',{name:'张三',age:20}); //监听 emitter.on("getDetail",(val) = >{ console.log(val) }) //取消监听 emitter.off("getDetail") //如果发送了多个,可监听全部 emitter.on("*",(type,val) = >{ console.log(type,val) //type就是类型 之前注册的getDetail }) //取消所有监听 emitter.all.clear();
核心原理
Vue3.x以后从实例中移除了 $on
,$off
和 $once
方法,$emit
仍然是现有 API 的一部分,只能实现子组件触发父组件的方法。
原理很简单,就是通过 map 的方法保存函数。
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); }); } }; }
到此这篇关于Vue3中事件总线mitt的使用方式的文章就介绍到这了,更多相关Vue3 事件总线mitt内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!