使用方法
./index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button class="emit">$emit 发布信息</button>
<button class="off">$off 解绑事件</button>
<script src="./bus.js"></script>
<script>
let bus = new Bus
console.log(bus)
// 订阅
console.log('订阅事件test')
bus.$on('test', function(arg) {
console.log('$on:', arg)
})
let emit = document.querySelector('.emit')
let off = document.querySelector('.off')
// 发布
emit.addEventListener('click', () => {
bus.$emit('test', 'emit发布的信息')
})
// 解绑
off.addEventListener('click', () => {
bus.$off('test')
console.log('解绑事件成功')
})
</script>
</body>
</html>
实现过程
./bus.js
class Bus {
constructor () {
this.callbacks = {} // 回调队列
}
$on (key, fn) {
this.callbacks[key] = fn // 订阅,将对应的事件回调保存到回调队列中
}
$emit (name, args = null) {
if (this.callbacks[name]) {
this.callbacks[name](args) // 触发回调函数, 并传递参数
} else {
throw Error ('事件不存在')
}
}
$off (name) {
delete this.callbacks[name] // 删除事件队列对应的事件
}
}
用js实现了一个简单的
发布订阅者模式
;
vue中的
EventBus
就是这种原理,实现兄弟组件间进行通信;
vue也自带了
$on
$emit
这对方法,提供事件的派发与监听,所以对外暴露一个new Vue()
就可以调用vue自身的$on
$emit
进行组件间通讯了。