发布/订阅者模式核心
- 订阅者
- 发布者
信号中心(事件中心)
存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”一个信号,其它任务可以向信号中心“订阅”(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 = thisif (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) 即在事件中心取出相应的事件,并执行,从而实现发布
