兄弟组件也可以利用父传子,子传父的等实现,不再重复记录了
1.手写EventBus
目录结构:
bus.ts
type ParamsKey = string | number | symbol
type List = {
[key:ParamsKey]:Array<Function>
}
class Bus {
list:List
constructor(){
this.list = {}
}
emit(name:string,...args:Array<any>){
let eventName:Array<Function> = this.list[name]
eventName.forEach(fn => {
fn.apply(this,args)
})
}
on(name:string,callback:Function){
let fn:Array<Function> = this.list[name] || []
fn.push(callback)
this.list[name] = fn
}
Off(name:string){
if(this.list[name]){
delete this.list[name]
}
}
}
let bus = new Bus()
export default bus
A.vue
<template>
<div class="container">A组件
<el-button @click="toEmit">派发emit</el-button>
</div>
</template>
<script setup lang="ts">
import { ref,inject,Ref } from 'vue'
import bus from './bus'
const flag = ref<Boolean>(false)
const toEmit = () =>{
bus.emit('fromA',flag)
}
B.vue
<template>
<div class="container">B组件{{ con }}</div>
</template>
<script setup lang="ts">
import {ref,onMounted,onBeforeMount,onUpdated} from 'vue'
import bus from './bus'
const con = ref()
onBeforeMount(()=>{
bus.on('fromA',(res:boolean)=>{
console.log(res);
con.value = res
})
})
onUpdated(()=>{
console.log('update');
bus.Off('fromA')
})
</script>
index.vue
<template>
<A></A>
<B></B>
</template>
<script setup lang="ts">
import A from './A.vue'
import B from './B.vue'
</script>
2.使用官方推荐的Mitt
mitt.ts
import mitt from 'mitt'
export const bus = mitt()
A.vue
<template>
<div class="container">A组件
<el-button @click="toEmit">派发emit</el-button>
</div>
</template>
<script setup lang="ts">
import { ref,inject,Ref } from 'vue'
import {bus} from './mitt'
const flag = ref<Boolean>(false)
const toEmit = () =>{
bus.emit('fromA',flag)
}
B.vue
<template>
<div class="container">B组件{{ con }}</div>
</template>
<script setup lang="ts">
import {ref,onMounted,onBeforeMount,onUpdated} from 'vue'
import {bus} from './mitt'
const con = ref()
onBeforeMount(()=>{
bus.on('fromA',(res:boolean)=>{
console.log(res);
con.value = res
})
})
onUpdated(()=>{
console.log('update');
bus.Off('fromA')
})
</script>