发布/订阅者模式核心

    • 订阅者
    • 发布者
    • 信号中心(事件中心)


      存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”一个信号,其它任务可以向信号中心“订阅”(subscribe)这个信号,从而知道什么时候可以开始执行,这就是发布/订阅模式。

    该模式再Vue中的应用:

    • 父子组件通信 on emit ```javascript let vm = new Vue()

      vm.$on(‘dataChange’,() => {

      1. console.log('dataChange')

      })

      vm.$on(‘dataChange’,()=>{

      1. console.log('xxxx')

      })

      vm.$emit(‘dataChange’);

    1. vm.$on 监听dataChange 事件,类似于订阅者<br />vm.$emit 发布dataChange 事件 ,类似于发布者
    2. ```javascript
    3. //vm.$on 源码
    4. Vue.prototype.$on = function (event, fn) {
    5. const vm: Component = this
    6. if (Array.isArray(event)) {
    7. for (let i = 0, l = event.length; i < l; i++) {
    8. this.$on(event[i], fn)
    9. }
    10. } else {
    11. (vm._events[event] || (vm._events[event] = [])).push(fn)
    12. }
    13. return vm
    14. }

    如果event事件是一个数组,依次调用vm.$on
    如果event 不是一个数组,就在事件中心 vm._events 查看是否已经注册过该事件 ,将回调函数存到数组中,一个事件可以绑定多个回调函数

    • 兄弟组件通信

    兄弟组件通信,使用事件车(事件总线)$bus 进行通信 $bus 是Vue的一个实例 ,$bus = vm = this

    1. // 创建一个空页面 Bus.js
    2. //import vue from 'Vue.js'
    3. //export default new vue()
    4. //import bus from '/Bus.js'
    5. let $bus = new Vue();
    6. //组件A中发布消息
    7. sendMess:function(){
    8. $bus.$emit('send_mess',{ mess:"这是组件A发布的消息" });
    9. }
    10. //组件B中订阅消息,在created或mounted钩子函数设置订阅
    11. created:function(){
    12. $bus.$on('send_mess',(params)=>{
    13. console.log("在这里处理接受到的消息")
    14. })
    15. }
    16. 同时订阅到的消息,要在beforeDestory中取消
    17. beforeDestory() {
    18. $bus.$off("send_mess");
    19. }

    简易发布/订阅类

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>发布/订阅者模式</title>
    7. </head>
    8. <body>
    9. <script>
    10. class EventEmitter {
    11. constructor() {
    12. this.subs = Object.create(null)
    13. }
    14. // 订阅
    15. $on(eventType,handler) {
    16. this.subs[eventType] = this.subs[eventType] || []
    17. this.subs[eventType].push(handler)
    18. }
    19. // 发布
    20. $emit(eventType) {
    21. if(this.subs[eventType]){
    22. this.subs[eventType].forEach(func => {
    23. func()
    24. });
    25. }
    26. }
    27. }
    28. let em =new EventEmitter();
    29. em.$on('event', () => {
    30. console.log('1号订阅')
    31. })
    32. em.$on('event', () => {
    33. console.log('2号也订阅')
    34. })
    35. setTimeout(()=>{
    36. em.$emit('event')
    37. },3000)
    38. </script>
    39. </body>
    40. </html>

    this.subs 类似于事件中心,存放着各种事件和事件的对应的回调函数
    图片.png
    $emit(event) 即在事件中心取出相应的事件,并执行,从而实现发布