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); });
  }
 };
}

 

posted @ 2022-04-26 17:38  如意酱  阅读(3523)  评论(0编辑  收藏  举报