设计模式 ~ 发布订阅模式

概念

用于实现对象之间的松耦合通信;
在该模式中,存在一个或多个发布者(Publishers)和一个或多个订阅者(Subscribers);
发布者负责发布消息,而订阅者负责订阅感兴趣的消息并在接收到消息时做出相应的处理。

对比观察者模式

Subject 和 Observer 直接绑定,中间无媒介;
Publisher 和 Observer 相互不认识,中间有媒介;
在这里插入图片描述

演示

on 方法:订阅者可以注册自己来接收特定事件的通知;
off 方法:订阅者可以取消对特定事件的订阅;
emit 方法:发布者可以发布特定事件及其相关的数据。

class PubSub {
  subscribers = {}
  // 订阅
  on(eventName, callback) {
    if (!this.subscribers[eventName]) {
      this.subscribers[eventName] = []
    }
    this.subscribers[eventName].push(callback)
  }
  // 取消订阅
  off(eventName, callback) {
    if (this.subscribers[eventName]) {
      // 订阅函数的索引
      const index = this.subscribers[eventName].findIndex(item => item === callback)
      if (index !== -1) {
        this.subscribers[eventName].splice(index, 1)
      }
    }
  }
  // 发布
  emit(eventName, data) {
    if (this.subscribers[eventName]) {
      this.subscribers[eventName].forEach(callback => {
        callback(data)
      })
    }
  }
}
const pubsub = new PubSub()
function fn1(data) {
  console.log('订阅1收到', data)
}
function fn2(data) {
  console.log('订阅2收到', data)
}
pubsub.on('message', fn1) // 订阅
pubsub.on('message', fn2) // 订阅
pubsub.emit('message', '发布的消息') // 发布
console.log(pubsub)
pubsub.off('message', fn2) // 取消订阅

VUE

Vue2 实例本身就支持自定义事件,但 Vue3 不再支持;
推荐使用 mitt ,https://github.com/developit/mitt
mitt 没有 once ,也可以使用 event-emitter https://www.npmjs.com/package/event-emitter

创建单独的 .js 文件、保证单例性

import mitt from 'mitt'
const emitter = mitt() // 单例
export default emitter

发布和订阅

emitter.on('change', () => {
    console.log('change')
})
emitter.emit('change')

即时销毁

created() {
    emitter.on('change', this.fn)
},
beforeUnmount() {
    emitter.off('change', this.fn)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值