一个非常简单的-发布订阅模式

815 阅读1分钟

使用方法

./index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <button class="emit">$emit 发布信息</button>
  <button class="off">$off 解绑事件</button>
  <script src="./bus.js"></script>
  <script>
    let bus = new Bus
    console.log(bus)

    // 订阅
    console.log('订阅事件test')
    bus.$on('test', function(arg) {
      console.log('$on:', arg)
    })

    let emit = document.querySelector('.emit')
    let off = document.querySelector('.off')
    
    // 发布
    emit.addEventListener('click', () => {
      bus.$emit('test', 'emit发布的信息')
    })

    // 解绑
    off.addEventListener('click', () => {
      bus.$off('test')
      console.log('解绑事件成功')
    })
  </script>
</body>
</html>

实现过程

./bus.js

class Bus {
  constructor () {
    this.callbacks = {} // 回调队列
  }
  $on (key, fn) {
    this.callbacks[key] = fn  // 订阅,将对应的事件回调保存到回调队列中
  }
  $emit (name, args = null) {
    if (this.callbacks[name]) {
      this.callbacks[name](args) // 触发回调函数, 并传递参数
    } else {
      throw Error ('事件不存在')
    }
  }
  $off (name) {
    delete this.callbacks[name] // 删除事件队列对应的事件
  }
}

用js实现了一个简单的发布订阅者模式

vue中的 EventBus 就是这种原理,实现兄弟组件间进行通信;

vue也自带了$on $emit这对方法,提供事件的派发与监听,所以对外暴露一个 new Vue()就可以调用vue自身的$on $emit进行组件间通讯了。