vue3-mitt发布订阅插件

542 阅读4分钟

定义

Vue 3 Mitt 是一个用于在 Vue 3 中实现事件总线的插件。它提供了一种简单的方式来进行组件之间的通信,而无需使用全局事件总线或手动创建和管理事件。

  1. 安装 Vue 3 Mitt 插件:
npm install mitt -S
  1. 在需要使用事件总线的地方导入并创建一个 Mitt 实例:
import mitt from 'mitt';
const emitter = mitt();
  1. 在发送事件的组件中,使用 emitter.emit() 方法触发事件:
emitter.emit('eventName', payload); 
这里的 `'eventName'` 是事件的名称,`payload` 是要传递给事件处理程序的数据。
  1. 在接收事件的组件中,使用 emitter.on() 方法监听事件并定义事件处理程序:
emitter.on('eventName', (payload) => {
// 处理事件的逻辑
});
这里的 `'eventName'` 是要监听的事件名称,事件处理程序是一个回调函数,它接收事件的数据作为参数。

// 订阅所有事件,回调函数接收2个参数,一个是事件名,一个是对应事件传递的参数
emitter.on('*',(eventName, payload)=>{console.log('回调函数,处理传递的参数', eventName, payload)})
  1. 可选:在不需要监听事件的组件中,使用 emitter.off() 方法取消事件监听:
  • 如果在调用 emitter.off() 方法时不传递回调函数,即不指定要取消的特定事件处理程序,那么该事件的所有监听器将被移除。
  • 具体来说,如果调用 emitter.off('eventName'),则将移除所有与 'eventName' 相关的事件监听器
  • 如果你只想取消特定的事件处理程序,而不是所有与事件相关的监听器,那么在调用 emitter.off() 方法时,确保传递要取消的特定事件处理程序作为参数。
emitter.off('eventName', eventHandler);
这里的 `'eventName'` 是要取消监听的事件名称,`eventHandler` 是之前定义的事件处理程序。

// 取消所有与 'eventName' 相关的事件监听器 
emitter.off('eventName');

通过以上步骤,你可以在 Vue 3 中使用 Vue 3 Mitt 插件来实现组件之间的事件通信。它提供了一个简单而灵活的方式来发送和接收事件,使组件之间的通信更加方便和可维护。

导入使用的方式

工具包
import mitt from 'mitt';

const emitter = mitt();

export default emitter;

父组件

<template>
  <div>
    <div class="box">index组件</div>
    <div><t-button @click="hclick">取消事件监听</t-button></div>
    <br />
    <b-vue />
    <br />
    <c-vue />
  </div>
</template>

<script lang="ts">
export default {
  name: 'ApplyAWSIndex',
};
</script>
<script setup lang="ts">
import BVue from './B.vue';
import CVue from './C.vue';
// 引入插件mitt实例
import emitter from '@/utils/event-bus';

const callback = (val) => {
  console.log('index组件-on:', val);
};
// 订阅事件
emitter.on('happen', callback);

const hclick = () => {
  console.log('index组件-off,不再订阅事件');
  // 不加回调函数,会把订阅该事件的所有回调函数都清空,会影响其他仍需要监听的组件
  emitter.off('happen', callback);
};
</script>

<style scoped lang="less">
.box {
  background-color: yellow;
}
</style>
B组件
<template>
  <div style="border: 1px solid black; height: 800px; background-color: #1dc8e5">
    我是B
    <div>
      <t-button @click="hclick">点我发布事件</t-button>
    </div>
    <br />
  </div>
</template>

<script setup lang="ts">
import emitter from '@/utils/event-bus';

const hclick = () => {
  console.log('B组件发布事件');
  emitter.emit('happen', '我是发布事件传递的值specialValue');
};
</script>

<style scoped></style>
C组件
<template>
  <div style="border: 1px solid black; height: 500px; background-color: #3d87ff">我是C</div>
</template>

<script setup lang="ts">
import emitter from '@/utils/event-bus';

emitter.on('happen', (val) => {
  console.log('C组件-on:', val);
});
</script>

<style scoped></style>

image.png

emitter.off()例子

当一个组件被销毁或不再需要监听事件时,可以使用 emitter.off() 方法来取消事件监听。下面是一个具体的例子:

import { onUnmounted } from 'vue';
import mitt from 'mitt';

const emitter = mitt();

// 组件 A
export default {
  mounted() {
    // 在组件 A 中监听事件
    emitter.on('eventName', this.eventHandler);
  },
  methods: {
    eventHandler(payload) {
      console.log('Event received:', payload);
    }
  },
  unmounted() {
    // 在组件 A 被销毁时取消事件监听
    emitter.off('eventName', this.eventHandler);
  }
}

在这个例子中,我们使用 Vue 3 的 onUnmounted 钩子函数来监听组件的销毁事件。在组件 A 的 mounted 钩子函数中,我们使用 emitter.on() 方法来监听名为 'eventName' 的事件,并指定事件处理程序为 eventHandler 方法。

然后,在组件 A 的 unmounted 钩子函数中,我们使用 emitter.off() 方法来取消对 'eventName' 事件的监听,同时指定要取消的事件处理程序为 eventHandler 方法。

这样,当组件 A 被销毁时,unmounted 钩子函数会触发,从而调用 emitter.off() 方法取消对 'eventName' 事件的监听。这样可以确保在组件 A 不再需要监听事件时,及时取消事件监听,避免不必要的事件处理和资源浪费。

通过使用 emitter.off() 方法,我们可以在需要停止监听事件的组件中,及时取消事件监听,以提高代码的可维护性和性能。

全局导入方式

image.png

兄弟组件A

image.png

兄弟组件B

image.png

image.png

image.png

image.png