interface BusClass {
emit: (name: string) => void
on: (name: string, callback: Function) => void
}
type listType = {
[keyName: string | number]: Array<Function>
}
class eventBus implements BusClass {
/**
* list对象 用来存储需要侦听的on
* 数据结构如 list: { abusChange: [ ()=>{}, ()=>{} ] }
* 这个abusChange属性就是on的name,
* 而数组中的每一项function就是这个name在哪些组件中需要侦听的回调
*/
list: listType
constructor() {
this.list = {}
}
// on可以认为是订阅者
on(name: string, callback: Function) {
/**
* 两种情况: this.list[name] || []
* 1.当前执行的on的name不存在,说明该name是第一次加入list,
* 那么这种情况就直接附一个空数组, 并且给这个空数组push回调函数,也就是 arr = [ () => {} ]
* 2. 当前执行的on的name已经存在,说明该name已经加入了list,也就是这个on(name, ()=> {})在某一个组件中已经加入了侦听,
* 这种情况,就给arr附值this.list[name],并且push新的回调,arr = [ () => {}, () => {}, ... ]
* 然后this.list[name]再附值arr 就得到了 list = { name: [ () => {}, ... ] }
*/
const arr: Array<Function> = this.list[name] || []
arr.push(callback)
this.list[name] = arr
}
// emit可以认为是发布者
emit(name: string, ...args: Array<any>) {
/**
* 这里取出emit执行的时候对应的name [()=>{}, ...]
* 然后循环 并且执行该数组中的每一项回调函数,将emit传入的值通过apply传给on的回调
*/
const callbacks: Array<Function> = this.list[name]
callbacks.forEach((fn) => {
fn.apply(this, args)
})
}
}
export default new eventBus()
例子:
app.vue
<script setup lang="ts">
import ACom from './components/A.vue'
import BCom from './components/B.vue'
import CCom from './components/C.vue'
</script>
<template>
<ACom></ACom>
<BCom></BCom>
<CCom></CCom>
</template>
<style lang="scss" scoped></style>
A.vue
<script setup lang="ts">
import { ref } from 'vue'
import bus from '../utils/eventBus'
let count = ref(0)
const handleAddCount = () => {
count.value++
bus.emit('countChange', count.value)
}
</script>
<template>
<button @click="handleAddCount">A组件计数+</button>
</template>
<style scoped></style>
B.vue / C.vue
<script setup lang="ts">
import { ref } from 'vue'
import bus from '../utils/eventBus'
let count = ref(0)
bus.on('countChange', (value: number) => {
count.value = value
})
</script>
<template>
<h2>B组件接收A组件的值 {{ count }}</h2>
</template>
<style scoped></style>
a,b,c组件分别是三个兄弟组件,由a组件来发布,b,c组件来订阅侦听a组件的count改变,并且响应;