>[danger]Vue:发布订阅(如何实现发布订阅) **发布-订阅模式也叫做观察者模式**。通过一对一或者一对多的依赖关系,当对象发生改变时,订阅方都会收到通知。在现实生活中,也有很多类似场景,比如我需要在购物网站上购买一个产品,但是发现该产品目前处于缺货状态,这时候我可以点击有货通知的按钮,让网站在产品有货的时候通过短信通知我。 在实际代码中其实发布-订阅模式也很常见,比如我们点击一个按钮触发了点击事件就是使用了该模式 ``` <ul id="ul"></ul> <script> let ul = document.querySelector('#ul') ul.addEventListener('click', (event) => { console.log(event.target); }) </script> ``` 在 Vue 中,如何实现响应式也是使用了该模式。对于需要实现响应式的对象来说,在`get`的时候会进行依赖收集,当改变了对象的属性时,就会触发派发更新。 --- 以下是如何实现发布-订阅模式的例子 ``` class EventCenter{  // 1. 定义事件容器,用来装事件数组 let handlers = {} ​  // 2. 添加事件方法,参数:事件名 事件方法  addEventListener(type, handler) {    // 创建新数组容器    if (!this.handlers[type]) {      this.handlers[type] = []   }    // 存入事件    this.handlers[type].push(handler) } ​  // 3. 触发事件,参数:事件名 事件参数  dispatchEvent(type, params) {    // 若没有注册该事件则抛出错误    if (!this.handlers[type]) {      return new Error('该事件未注册')   }    // 触发事件    this.handlers[type].forEach(handler => {      handler(...params)   }) } ​  // 4. 事件移除,参数:事件名 要删除事件,若无第二个参数则删除该事件的订阅和发布  removeEventListener(type, handler) {    if (!this.handlers[type]) {      return new Error('事件无效')   }    if (!handler) {      // 移除事件      delete this.handlers[type]   } else {      const index = this.handlers[type].findIndex(el => el === handler)      if (index === -1) {        return new Error('无该绑定事件')     }      // 移除事件      this.handlers[type].splice(index, 1)      if (this.handlers[type].length === 0) {        delete this.handlers[type]     }   } } } ```