TypeScript开发记录


生态

mitt

vue3 不再建议使用 EventBus 作为全局事件总栈,改为推荐 mitt.js 库。

mitt 不依赖任何库,体积仅有 200bytes。也不依赖 vue 实例,这使得它可以在任何地方使用。

快速开始

1
npm install --save mitt

与 vue2 EvenBus 类似的使用方式

1
2
3
// mittBus.ts
import mitt from "mitt";
export default mitt();

使用方式

其使用方式与 EventEmitter 类似:

  • all:事件列表,map 类型
  • on:注册时间
  • off:移除事件
  • all.clear:清空事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 引入上面注册的 mitt.js
import mittBus from "./mittBus";

// 单事件监听方法
const mariHandle = data => console.log( data );

// 通用事件监听方法
const commonHandle = ( event, data ) => console.log( event, data )

// 监听事件:接收一个事件传递数据参数
mittBus.on( "mari", mariHandle );

// 监听全部事件:接收两个参数,事件名与事件传递数据
mittBus.on( "*", commonHandle );

// 触发事件
mittBus.emit( "asuka", { auth: "author" } );

// 注销事件:需要传入定义事件的方法名
mittBus.off( "mari", mariHandle );

// 注销全部事件:需要传入定义事件的方法名
mittBus.off( "*", commonHandle );

// 清空事件
mittBus.all.clear();

原理

本质是使用 map 以键值对的方式保存事件,并通过闭包长期保存不被释放。个人实现方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
export function mitt( all = new Map() ) {
return {
all,
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 ) {
const index = handlers.indexOf( handler );
if ( index !== -1 ) {
handlers.splice( index, 1 );
}
}
},
emit( type, data ) {
const handlers = all.get( type ) || [];
handlers.slice().map( handler => {
handler( data );
} );
if ( type !== "*" ) {
const common = all.get( "*" ) || [];
common.slice().map( handler => {
handler( type, data );
} );
}
}
}
}

问题

vue3 + echart5 时报错

在 vue3 中使用 echart5 出现如下报错。

1
Cannot read properties of undefined (reading ‘type‘)

这是深层响应 Proxy 应用到了整个 echart 实例导致的问题,即对 echart 实例使用了 refreactive

不仅仅会报错,这也是 echart 官方不建议的行为,这样会影响实例底层的运行,并且会极大的降低图表的展示性能,官方解释

可以通过定义普通变量或使用 shallowRef 等浅层响应保存 echart 实例来解决这个问题。

1
2
3
4
const chart = echart.init( dom );
// 使用浅层响应
const chartRef = shallowRef( null );
chartRef.value = echart.init( dom );