发布/订阅者模式核心
- 订阅者
- 发布者
信号中心(事件中心)
存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”一个信号,其它任务可以向信号中心“订阅”(subscribe)这个信号,从而知道什么时候可以开始执行,这就是发布/订阅模式。
该模式再Vue中的应用:
父子组件通信 on emit ```javascript let vm = new Vue()
vm.$on(‘dataChange’,() => {
console.log('dataChange')
})
vm.$on(‘dataChange’,()=>{
console.log('xxxx')
})
vm.$emit(‘dataChange’);
vm.$on 监听dataChange 事件,类似于订阅者<br />vm.$emit 发布dataChange 事件 ,类似于发布者
```javascript
//vm.$on 源码
Vue.prototype.$on = function (event, fn) {
const vm: Component = this
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
this.$on(event[i], fn)
}
} else {
(vm._events[event] || (vm._events[event] = [])).push(fn)
}
return vm
}
如果event事件是一个数组,依次调用vm.$on
如果event 不是一个数组,就在事件中心 vm._events 查看是否已经注册过该事件 ,将回调函数存到数组中,一个事件可以绑定多个回调函数
- 兄弟组件通信
兄弟组件通信,使用事件车(事件总线)$bus 进行通信 $bus 是Vue的一个实例 ,$bus = vm = this
// 创建一个空页面 Bus.js
//import vue from 'Vue.js'
//export default new vue()
//import bus from '/Bus.js'
let $bus = new Vue();
//组件A中发布消息
sendMess:function(){
$bus.$emit('send_mess',{ mess:"这是组件A发布的消息" });
}
//组件B中订阅消息,在created或mounted钩子函数设置订阅
created:function(){
$bus.$on('send_mess',(params)=>{
console.log("在这里处理接受到的消息")
})
}
同时订阅到的消息,要在beforeDestory中取消
beforeDestory() {
$bus.$off("send_mess");
}
简易发布/订阅类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发布/订阅者模式</title>
</head>
<body>
<script>
class EventEmitter {
constructor() {
this.subs = Object.create(null)
}
// 订阅
$on(eventType,handler) {
this.subs[eventType] = this.subs[eventType] || []
this.subs[eventType].push(handler)
}
// 发布
$emit(eventType) {
if(this.subs[eventType]){
this.subs[eventType].forEach(func => {
func()
});
}
}
}
let em =new EventEmitter();
em.$on('event', () => {
console.log('1号订阅')
})
em.$on('event', () => {
console.log('2号也订阅')
})
setTimeout(()=>{
em.$emit('event')
},3000)
</script>
</body>
</html>
this.subs 类似于事件中心,存放着各种事件和事件的对应的回调函数
$emit(event) 即在事件中心取出相应的事件,并执行,从而实现发布