Vue3中事件总线(mitt库)的使用

1,454 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

前言

在vue中使用全局事件总线可以省去很多组件间通信的麻烦,例如可能会出现的子传父,父再传子的多个传递过程。但是Vue3从实例中移除了 onon、off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库

Vue3官方有推荐一些库,例如 mitttiny-emitter

这里我们主要讲解一下mitt库的使用

使用

首先,我们需要先安装这个库:npm install mitt

其次,我们可以封装一个工具eventbus.js

import mitt from 'mitt';

const emitter = mitt();
// export const emitter1 = mitt();  //可针对不同组件的事件传递创建多个对象
// export const emitter2 = mitt();
// export const emitter3 = mitt();

export default emitter;

假设 A组件 与 B组件 是没有直接关系的两个组件,如兄弟组件

在项目中可以这样使用它们:

我们在A组件中触发事件:

<script setup>
  import emitter from './utils/eventbus';
  const btnClick = () => {
    console.log("about按钮的点击");
    emitter.emit("aClick", {name: "WO", age: 18});
    // emitter.emit("louis", {name: "louis", age: 30});
  }
</script>

我们在B组件中监听事件:

<script setup>
  import emitter from './utils/eventbus';
  emitter.on("aClick", (info) => {
    console.log("aClick:", info);
  });

  // 可监听多个事件
  emitter.on("louis", (info) => {
    console.log("louis:", info);
  });

  // 监听所有事件,需要传递两个参数,第一个为事件类型,第二个为传递的数据信息
  emitter.on("*", (type, info) => {
    console.log("* listener:", type, info);
  })
  
</script>

在某些情况下我们可能希望取消掉之前注册的函数监听:

  1. 取消所有监听

image.png

  1. 取消某一个监听

image.png

总结

事件总线的Mitt库,优点在于灵活,缺点也很明显。

  1. 订阅和发布必须成对出现,不然就没有意义
  2. 由于在页面使用里的灵活性,一旦事件多了后,难以对事件进行维护
  3. 在订阅事件的组件里,必须手动销毁监听,否则会引发多次执行
  4. 对于一些包含业务逻辑的通信,复用性差,需要在多个地方重复写逻辑

中大型项目不推荐用EventBus,建议用VuexPinia,方便日后维护。
小型项目,涉及到多处跨组件通信的情况,可以考虑使用。