vue3中组件通信mitt(兄弟间、任意组件间)

概况

vue3中常见的组件通信

组件关系传递方式
父传子1. props
2. v-model
3. $refs
4. 默认插槽、具名插槽
子传父1. props
2. 自定义事件
3. v-model
4. $parent
5. 作用域插槽
祖传孙、孙传祖1. $attrs
2. provide、inject
兄弟间、任意组件间1. mitt
2. pinia


Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中事件总线模式已经被移除,官方建议使用外部的、实现了事件触发器接口的库,例如 mitt 或 tiny-emitter。今天来说说mitt

安装

npm install --save mitt

yarn add mitt

pnpm install mitt

基本用法

mitt().on() 绑定事件

用来绑定事件,接收两个参数,第一个参数是事件名,第二个参数是事件触发时的回调函数;

mitt().emit() 触发事件

用来触发事件,参数为事件名;

mitt().off()卸载某个事件

用来解绑事件,参数为事件名;

mitt().all.clear()卸载全部事件

all有clear属性,直接调用clear()属性可以解绑全部事件。

//绑定事件test1,当事件触发时执行回调
emitter.on('test1',()=>{
    console.log('test1被调用了')
})

//绑定事件test2,当事件触发时执行回调
emitter.on('test2',()=>{
    console.log('test2被调用了')
})

//绑定事件test3,当事件触发时执行回调
emitter.on('test3',()=>{
    console.log('test3被调用了')
})

//触发事件,每间隔1秒触发一次
setInterval(()=>{
    //触发事件test1
    emitter.emit('test1')
    //触发事件test2
    emitter.emit('test2')
    //触发事件test3
    emitter.emit('test3')
},1000)

//解绑事件,2秒后解绑test1
setTimeout(()=>{
    emitter.off('test1')
    console.log('--------test1解绑了')
},2000)

//解绑事件,4秒后解绑所有事件
setTimeout(()=>{
    emitter.all.clear()
    console.log('--------所有的事件解绑了')
},4000)

使用方式

使用方式一:全局使用

在 main.ts 中注册挂载到全局

import { createApp } from 'vue'
import App from './App.vue'

//引入
import mitt from 'mitt'

const app = createApp(App)
 
// vue3挂载到全局
app.config.globalProperties.$mitt = mitt();
 
app.mount('#app')

在home.vue组件中使用 emit 发送信息

<template>
    <div class="home-container">
        <p>这里是home组件</p>
        <button @click="sendMitt">$mitt发送数据</button>
        <About></About>
    </div>
</template>
 

<script lang="ts" setup>
import { getCurrentInstance, ref, ComponentInternalInstance } from 'vue';
import About from '../about/about.vue'
 
const { appContext } = getCurrentInstance() as ComponentInternalInstance;
const money = ref<number>(98);
 
const sendMitt = () => {
    appContext.config.globalProperties.$mitt.emit('moneyEvent', money.value += 2);
}
</script>

在about.vue组件中使用 on 接收信息

使用方式二:组件中引用

新建bus.ts 文件

import mitt from "mitt";
 
const emiter = mitt();
 
export default emiter;

在home.vue组件中引入并使用 emit 发送信息

<template>
    <div class="home-container">
        <p>这里是home组件</p>
        <button @click="sendMitt">$mitt发送数据</button>
        <About></About>
    </div>
</template>
 
<script lang="ts" setup>
import { ref } from 'vue';
import About from '../about/about.vue'
import emitter from '../../utils/bus'
 
const money = ref<number>(98);
 
const sendMitt = () => {
    emitter.emit('moneyEvent', money.value += 2);
}
 
</script>
 

在about.vue组件中引入并使用 on 接收信息


<template>
    <div class="about-container">
        <p>这里是about组件</p>
        <p>接收到的数据:{{ amount }}</p>
    </div>
</template>
 
<script lang="ts" setup>
import { ref, onBeforeMount, onMounted } from 'vue';
import emitter from '../../utils/bus'
 
const amount = ref(0);
 
onMounted(() => {
    emitter.on('moneyEvent', (res: any) => {
        amount.value = res;
    });
})
 
onBeforeMount(() => {
    emitter.off('moneyEvent');
});
 
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值