0%

实现Vue中EventBus通信方式

Vue 非父子组件可以用 Event Bus 通信,用起来很简单但要不只是会使用 api,还要懂大致原理,于是自己实现了一下。

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class EventBus {
constructor() {
this._events = new Map()
}

// 注册事件
on(name, fn) {
const handler = this._events.get(name)
if (!handler) {
this._events.set(name, [])
}
this._events.get(name).push(fn)
}

/**
* 触发事件
* 可以用apply与call两种方法,在少数参数时call的性能更好,多个参数时apply性能更好
* Node的Event模块就在三个参数以下用call否则用apply.
*/
emit(name, ...args) {
const handler = this._events.get(name)
if (!handler) return
handler.forEach(cb => {
if (args.length >= 3) {
cb.apply(this, args)
} else {
cb.call(this, ...args)
}
})
}

// 只被触发一次的事件
once(name, fn) {
const cb = (...args) => {
if (args.length >= 3) {
fn.apply(this, args)
} else {
fn.call(this, ...args)
}
this.off(name, cb)
}
this.on(name, cb)
}

// 取消事件
off(name, fn) {
if (typeof fn === 'undefined') {
// 没有传指定函数就移除所有同名事件
this._events.delete(name)
return
}
const handler = this._events.get(name)
if (!handler) return
let fnIndex = handler.findIndex(cb => cb === fn)
handler.splice(fnIndex, 1)
if (!this._events.get(name).length) {
this._events.delete(name)
}
}
}
-------------本文结束感谢您的阅读-------------