js中訂閱發佈模式bus

export default {
  list: {}, // 事件中心集中地
  /**
   * 發佈訂閱
   * @param {string} name 事件名
   * @param  [...args]
   */
  $emit: function (name) {
    if (this.list[name]) {
      for (let i = 0; i < this.list[name].length; i++) {
        this.list[name][i].apply(this, Array.from(arguments).slice(1));
      }
    }
  },
  /**
   * 訂閱一次後取消訂閱
   * @param {string} name 事件名
   * @param {*} fn
   */
  $once: function (name, fn) {
    function on() {
      // 觸發一次後移除
      fn.apply(this, arguments);
      this.$off(name, on);
    }
    // 加個標識,如一次都沒觸發的時候也可以手動移除訂閱
    on.fn = fn;
    this.$on(name, on);
  },
  /**
   * 訂閱
   * @param {string|Array<strig>} name 事件名
   * @param {Function} fn
   * @returns
   */
  $on: function (name, fn) {
    // 傳入的數組循環調用訂閱
    if (Array.isArray(name)) {
      for (let i = 0; i < name.length; i++) {
        this.$on(name[i], fn);
      }
      return;
    }
    if (this.list[name]) {
      this.list[name].push(fn);
    } else {
      this.list[name] = [fn];
    }
  },
  /**
   * 取消訂閱
   * @param {string|Array<string>|null} name 事件名
   * @param {Function|null} fn
   * @returns
   */
  $off: function (name, fn) {
    // 沒傳入參數,清空所有訂閱
    if (!name) {
      this.list = {};
      return;
    }
    if (Array.isArray(name)) {
      for (let i = 0; i < name.length; i++) {
        this.$off(name[i], fn);
      }
      return;
    }
    const cbs = this.list[name];
    // 沒有訂閱,直接返回
    if (!cbs) return;
    // 沒有傳入對應的訂閱,清空所有相關訂閱
    if (!fn) {
      this.list[name] = null;
      return;
    }
    // 找到對應的訂閱刪除
    for (let i = 0; i < cbs.length; i++) {
      if (cbs[i] === fn || cbs[i].fn === fn) {
        cbs.splice(i, 1);
        break;
      }
    }
  }
};

event 用法
$on $on(evnet,callback), $on([evnet,evnet2],callback)
$off $off(), $off(event), $off(event,callback)
$once $once(evnet,callback)
$emit $emit(event), $emit(event,[...args])

html中使用

// 引入
<script type="module">
import bus from './bus.js';
// 掛載到window上
window.$bus = bus;
</script>
<script>
// 用法
// window.$bus.$on(event,callback), 訂閱
// window.$bus.$once(event,callback), 訂閱一次後移除訂閱
// window.$bus.$off(event,callback), 移除訂閱
// window.$bus.$emit(event,[...args]), 發佈
</script>

vue2中使用

// main.js中引入
import bus from './bus.js';
// 掛在到原型上,創建事件總線
Vue.prototype.$bus = bus;

// 用法
// this.$bus.$on(event,callback), 訂閱
// this.$bus.$once(event,callback), 訂閱一次後移除訂閱
// this.$bus.$off(event,callback), 移除訂閱
// this.$bus.$emit(event,[...args]), 發佈
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章