如何在vue3中使用$bus

311 阅读1分钟

自定义$bus及在vue3中的使用

自定义$bus

  1. 先看目录结构,主要看bus和main.js

image-20230220205303826.png

  1. 声明一个bus:
export default class Bus {
  constructor() {
    this.events = {};
  }
  $on(name, callback) {
    this.events[name] = this.events[name] || [];
    this.events[name].push(callback);
  }
  $emit(name, args) {
    if (this.events[name]) {
      this.events[name].forEach(callback => callback(args));
    }
  }
  $off(name, cb) {
    const cbArr = this.events[name];
    if (cbArr) {
      // 此处做了个优化,如果有cb则删除cb,若无cb则删除此name下的所有cb
      if (cb) {
        for (let index = 0; index < cbArr.length; index++) {
          const item = cbArr[index];
          if (item === cb) {
            cbArr.splice(index, 1);
            break;
          }
        }
      } else {
        delete this.events[name];
      }
    }
  }
}

挂载

在入口文件,通过provide挂载

import { createApp } from 'vue'
import Bus from './bus';
const $bus = new Bus();
createApp(App).provide('$bus', $bus).mount('#app');

使用

通过inject引入$bus,然后再绑定事件,触发事件

// Parent.vue
<script setup lang="ts">
import { inject } from 'vue';
const $bus: any = inject('$bus');
$bus.$on('test', (val: string) => {
  console.log((val));
});
</script>

// Child.vue
<script setup lang="ts">
// 某个事件中触发
const handleSelect = (key: string, keyPath: string[]) => {
  if (key === 'off') {
    $bus.$off('test');
  }
  $bus.$emit('test', 'aaa');
};
</script>