在vue3中 $ on,$off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口,因此大家熟悉的EventBus便无法使用了。然而我们习惯了使用EventBus,对于这种情况我们可以使用Mitt库
npm i mitt -S
首先要在全局挂载 mitt
在app.config.globalProperties上挂在$Bus
使用ts必须要拓展ComponentCustomProperties类型才能获得类型提示
main.ts
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
import mitt from 'mitt'
const Mit = mitt()
const app = createApp(App)
//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module 'vue' {
export interface ComponentCustomProperties {
$Bus: typeof Mit
}
}
//vue3挂载全局API
app.config.globalProperties.$Bus = Mit
app.mount('#app')
A.vue
在A中派发事件
getCurrentInstance是为了获取当前的组件实例
获取到当前组件的实例后,就可以在实例上的proxy获取到我们全局绑定的$Bus了
<template>
<div class="A">
A
<button @click="emitA"> 派发一个事件</button>
</div>
</template>
<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const emitA = () => {
instance?.proxy?.$Bus.emit('on-EmitA', 'mitt')
instance?.proxy?.$Bus.emit('on-EmitA2','mitt2')
}
</script>
<style lang="scss" scoped>
.A {
width: 200px;
height: 200px;
background-color: aqua;
.children {
display: flex;
justify-content: space-between;
}
}
</style>
B 中就可以监听到事件了
.on的第一个参数是事件的名称 这样可以一次监听一个事件
第一个参数传入 * 即监听全部事件 此时回调函数传入的第一个参数接受绑定的事件名称,第二个参数接受传入的参数
B.vue
<template>
<div class="B">
B
<br>
</div>
</template>
<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const Bus = (str: any) => {
console.log('b=====>str', str)
}
instance?.proxy?.$Bus.on('on-EmitA', Bus)//监听一个
//同样的也有off方法
instance?.proxy?.$Bus.off('on-EmitA', Bus)
instance?.proxy?.$Bus.all.clear()//清楚全部事件
// instance?.proxy?.$Bus.on('*', (type, str) => {
// console.log(type, 'b=====>str', str)
// })//监听多个
</script>
<style lang="scss" scoped>
@import '../style.scss';
.B {
width: 200px;
height: 200px;
background-color: $cloud-water;
}
</style>