持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
一、mitt的介绍
Mitt
是为浏览器设计的,但适用于任何 JavaScript
运行时。它没有依赖项,支持 IE9+。体积小,小于200
字节。在vue3
中代替了vue2
的EventBus
二、使用
导入
npm install --save mitt
然后在main.ts
的引入模块,创建实例并导出,这里是在untils
文件中单独创建untils.ts
文件
// 组件通信
import mitt from 'mitt'
export const emitter = mitt()
child组件传值
这里在组件中单独创建child1
,child2
文件
创建MittDemo
文件,将两个组件引入进去
现在单独处理两个文件
传递信息
从child1
传递参数到child2
,需要导入emitter
实例,调用emit
方法,传递事件和方法
// vue
<div>
child-1
<h2>child1组件</h2>
<button @click="child1Emitter">emitter事件</button>
</div>
// ts
import { emitter } from '@/utils/until'
const child1Emitter = () => {
emitter.emit('child2', '这是从child1传过来的参数')
}
child2页面监听该方法
import { emitter } from '@/utils/until'
emitter.on('child2', (e) => {
console.log(e)
})
这里,在child1
和child2
都写了发送和监听方法
页面如下
测试
点击child1
组件的事件
点击
child2
组件的事件
事件的调用
只需要在输出的位置,写需要调用的方法就可以了,参数也是从组件中传递过来的参数
点击child1按钮,组件child2响应
点击child2按钮,组件child1响应
父子组件通信
父组件调用子组件
在父组件导入实例,调用两个子组件的方法
// vue
<button @click="MittMain">mitt-Main主页事件</button>
// ts
import { emitter } from '@/utils/until'
const MittMain = () => {
emitter.emit('child1', 'mittMain')
emitter.emit('child2', 'mittMain')
}
效果如下
子组件调用父组件
在子组件child1
和child2
值都已经写了这个时间,这里只在MittDemo页面写下监听
这里*
是指监听所有事件
emitter.on('*', (e) => {
console.log('主页面Mitt-main', e)
})
返回的参数是事件名
如果想拿到具体的方法的参数,那么需要写明这个事件名称
如下
emitter.on('child1', (e) => {
console.log('主页面Mitt-main', e)
})
emitter.on('child2', (e) => {
console.log('主页面Mitt-main', e)
})
事件的注销与清除
删除给定类型的事件处理程序
emitter.off('child1', '删除')
清空所有事件
emitter.all.clear()
三、源码解读
这里先不说这个复杂的ts定义,只解读方法
on事件
- 通过
get
拿对应的值,如果handlers
为真,则将时间添加到监听队列 - 不存在,则在n里面设置键值对
on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
if (handlers) {
handlers.push(handler);
} else {
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
}
},
off事件
- 删除订阅消息的队列
- get判断值是否存在,如果存在,那么就直接通过
splice()
删除, 有两个值一个通过indexOf
拿下标,第二个是要删除的数量 >>>
表示无符号位移 它把无符号的 32 位整数所有数位整体右移。对于无符号数或正数右移运算,无符号右移与有符号右移运算的结果是相同的。- 对于负数来说,无符号右移将使用 0 来填充所有的空位,同时会把负数作为正数来处理,所得结果会非常大所以,使用无符号右移运算符时要特别小心,避免意外错误。
off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
if (handlers) {
if (handler) {
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
} else {
all!.set(type, []);
}
}
},
emit 事件
- 这里有两种情况,一种是发送type类型的时间,一种是*事件,
- 通map循环依次执行事件,这里使用了slice,返回一个新数组,原数组不会改变
emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
let handlers = all!.get(type);
if (handlers) {
(handlers as EventHandlerList<Events[keyof Events]>).slice().map((handler) => { handler(evt!); });
}
handlers = all!.get('*');
if (handlers) {
(handlers as WildCardEventHandlerList<Events>).slice().map((handler) => { handler(type, evt!); });
}
}
暂时就这么多,有问题或者错的东西,请留言,谢谢!!!