发表订阅者模式
用于实现对象之间的松耦合通信;
在该模式中,存在一个或多个发布者(Publishers)和一个或多个订阅者(Subscribers);
发布者负责发布消息,而订阅者负责订阅感兴趣的消息并在接收到消息时做出相应的处理。
对比观察者模式
Subject 和 Observer 直接绑定,中间无媒介;
Publisher 和 Observer 相互不认识,中间有媒介;
代码演示
function PubSub() {
this.subscribers = {}
}
subscribe 方法,订阅者可以注册自己来接收特定事件的通知;
unsubscribe 方法,订阅者可以取消对特定事件的订阅;
publish 方法,发布者可以发布特定事件及其相关的数据。
PubSub.prototype = {
subscribe: function (event, callback) {
if (!this.subscribers[event]) {
this.subscribers[event] = []
}
this.subscribers[event].push(callback)
},
unsubscribe: function (event, callback) {
if (this.subscribers[event]) {
var index = this.subscribers[event].indexOf(callback)
if (index !== -1) {
this.subscribers[event].splice(index, 1)
}
}
},
publish: function (event, data) {
if (this.subscribers[event]) {
this.subscribers[event].forEach(function (callback) {
callback(data)
})
}
}
}
创建实例
const pubsub = new PubSub()
订阅
pubsub.subscribe('message', function (data) {
console.log('收到消息:', data)
})
发布
pubsub.publish('message', '发布消息 ~~~')
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)
}