3-1-7-发布订阅模式

发布订阅模式

发布订阅模式和观察者模式是两种设计模式,在 Vue 中有各自的应用场景。两种模式的本质是相同的,但是还是有区别的,经常被混为一谈。

发布/订阅模式

  • 订阅者
  • 发布者
  • 信号中心

我们假定,存在一个"信号中心",某个任务执行完毕,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从开知道什么时候自己可以执行。这就叫做**“发布/订阅模式”(publish-subscribe pattern)**\

从自定义事件中看订阅/发布模式

let vm = new Vue()

// 订阅1
vm.$on('dataChange', () => {
  console.log('dataChange')
})

// 订阅2
vm.$on('dataChange', ()=> {
  console.log('dataChange1')
})

// 发布
vm.$emit('dataChange')

在上述的 vue 的自定义事件中,订阅1 和 订阅2 都订阅了同一个信号 “dataChange” ,当通过 vm.$emit(‘dataChange’) 发布这个信号的时候,订阅者们就会接收到信号开始执行各自的操作。这不过这里面的所有的订阅者和发布者都是一个角色 vm 。

从父子组件通信中看订阅/发布模式

// eventBus.js
// 事件中心
let eventHub = new Vue()

// ComponentA.vue
// 发布者
addTodo: function () {
  // 发布消息(事件)
  eventHub.$emit('add-todo', { text: this.newTodoText })
  this.newTodoText = ''
}
// ComponentB.vue
// 订阅者
created: function () {
  // 订阅消息(事件)
  eventHub.$on('add-todo', this.addTodo)
}

模拟 Vue 自定义事件的实现(发布/订阅模式)

<script>
  // 事件触发器
  class EventEmitter {
    constructor () {
      // { 'click': [fn1, fn2], 'change': [fn] }
      this.subs = Object.create(null) // 使用 Object.create() 的方法创建一个对象可以传递一个参数,这个参数的作用是去设置创建的对象的原型,设置为 null 声明这个对象没有原型属性,可以提高性能。以为这里的对象只需要存储键值对的形式,所以不需要原型。
    }

    // 注册事件
    $on (eventType, handler) {
      // 判断 this.subs[eventType] 是否存在,如果存在返回原数组,否则创建这个数组
      this.subs[eventType] = this.subs[eventType] || []
      this.subs[eventType].push(handler)
    }

    // 触发事件
    $emit (eventType) {
      // 这里的 $emit 只接收一个参数,是一个省略的写法,不考虑事件传参的情况
      if (this.subs[eventType]) {
        this.subs[eventType].forEach(handler => {
          handler()
        })
      }
    }
  }

  // 测试
  let em = new EventEmitter()

  em.$on('click', () => {
    console.log('我是 click 的订阅者1')
  })

  em.$on('click', () => {
    console.log('我是 click 的订阅者2')
  })

  em.$emit('click')
  
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值