自定义$bus及在vue3中的使用
自定义$bus
- 先看目录结构,主要看bus和main.js
- 声明一个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>