实现bus的emit和on

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改变,并且响应;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值