Vue: 兄弟组件利用自定义Bus传参

vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(path.resolve(), 'src')
    }
  }
})

 

 

import * as Console from 'console'


type BusClass = {
  emit: (name: string) => void,
  on: (name: string, callback: Function) => void
}

type CallbackName = string | number | symbol

type List = {
  [key: CallbackName]: Array<Function>
}

class Bus implements BusClass {
  list: List

  constructor() {
    this.list = {}
  }

  emit(name: string, ...args: Array<any>) {
    let callbacks: Array<Function> | undefined = this.list[name]
    if (callbacks === undefined) {
      console.warn(`event "${name}" is not bound`)
      return
    }
    callbacks.forEach(callback => {
      console.log('emit', this)
      callback.apply(this, args)  // this 为 Bus.ts 导出的实例, on方法如果使用ArrowFunction, 则无法使用this
    })
  }

  on(name: string, callback: Function) {
    let callbacks: Array<Function> = this.list[name] || []
    callbacks.push(callback)
    this.list[name] = callbacks
  }
}

export default new Bus()

App.vue

<template>
  <A></A>
  <B></B>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import A from './components/A.vue'
import B from './components/B.vue'


</script>


<style lang="less">

</style>

A.vue

<template>
  <div>
    <button @click="emitB">emit</button>
  </div>
</template>

<script lang="ts" setup>
import bus from '@/Bus.ts'
import { Ref, ref } from 'vue'


const emit = defineEmits(['on-click'])
let flag: Ref = ref<boolean>(true)
const emitB = () => {
  flag.value = ! flag.value
  bus.emit('on-click', flag)
}
</script>

B.vue

<template>
  <div>
    <time>{{ flag }}</time>
  </div>
</template>

<script lang="ts" setup>
import bus from '@/Bus.ts'
import { Ref, ref } from 'vue'


const flag = ref<boolean>(false)
// bus.on('on-click', (_flag: Ref) => {
//   console.dir(flag)
//   console.log('on',this)
//   flag.value = _flag.value
// })
bus.on('on-click', function (_flag: Ref) {
  console.dir(_flag)
  console.log('on', this)
  flag.value = _flag.value
})
</script>

 

 

 

posted @ 2022-03-26 10:28  ascertain  阅读(168)  评论(0编辑  收藏  举报