《Vue3 基础知识》事件总线 bus(与Vue2 有差异,使用 mitt 库)

前言

Vue2 与 Vue3 事件总线区别

解决方案

定义

Vue2 实现

// 文件 bus.js
import Vue from 'vue'

const bus = new Vue({});

export default bus;

Vue3 实现

题外话, 库 tiny-emitter 最后一次更新是 5年前库 mitt 更新是 2023.07.05。所以这里选择 库 mitt

先安装:

npm i mitt

再定义。注意代码 6-9 行 有转换,因为库 mitt 中的方法是带前缀 $,为了与 Vue 方法名兼容使用。

// 文件 bus.js
import mitt from 'mitt'

const bus = mitt();

// mitt 库中的方法是不带前缀$。为了与 Vue 方法名匹配。此处有转换。
bus.$on = bus.on;
bus.$off = bus.off;
bus.$emit = bus.emit;

export default bus;

有个坑

  • Vue2/Vue3 可传多个额外参数;
  • mitt 只能传一个额外参数,建议是 object 类型;

在这里插入图片描述

引入

Vue2Vue3 引入方式一样。

import bus from './bus.js'

使用

Vue2Vue3 使用方式也一样。但有上述提到的传递参数个数问题!

// 触发事件
bus.$emit('foo', 'test');

// 监听事件
bus.$on('foo', foo);

// 取消监听
bus.$off('foo', foo);

// 测试方法
function foo(e) {
	console.log('foo', e);
}

延伸知识

vm. e m i t 与 b u s . emit 与 bus. emitbus.emit 区别

vm.$emit

  • Vue 实例方法,且 Vue2 / Vue3 都有此方法;
  • 用于子组件父组件传递消息,通过方法 $emit 触发父组件上的自定义事件,并传参数;
  • 可传递任意 多个额外参数
// 子组件,触发事件
this.$emit('on-param-change', p1, p2);


// 父组件,监听事件
<my-parents @on-param-change="onParamChange" />
onParamChange (p1, p2) {
    console.log(p1, p2);
}

bus.$emit

  • 是上述 库 mitt 的方法,注意原生是 emit,不带 $
  • 可创建一个事件总线,在整个应用中做全局事件监听
  • 只能传递 一个额外参数
import bus from './bus.js'

// 触发事件
bus.$emit('on-param-change', {p1, p2});

// 监听事件
bus.$on('on-param-change', (obj) {
    console.log(obj.p1, obj.p2);
});

如果你没接触过GoGoCode,下小节可忽略

GoGoCode 中的 $emit 方法

GoGoCode 转换文件 /utils/gogocodeTransfer 封装了 $on, $once, $off, $emit 方法。

  • 也是 Vue3 移除 $on$off$once 实例方法 的解决方案之一;

  • 但在自动转换过程中,它把 vm.$emitbus.$emit 的方法都转了;

  • 所以出现了第三种方式;

GoGoCode 兼容 vm.$emit 方法

  • GoGoCode 方式:第一个参数是 this 组件实例对象;
// 使用 gogocode 的写法
import { $on, $off, $emit } from './utils/gogocodeTransfer'

$emit(this, 'tool-click', type, num);
  • vm.$emit 方式:可传多个额外参数。如果是父子组件传递消息,推荐此原生方式
// 使用 Vue 原生的写法
this.$emit('tool-click', type, num);

GoGoCode 兼容 bus.$emit 方法

  • GoGoCode 方式:第一个参数是 bus 对象(mitt)。它的有优点是可传递任意多个额外参数;
import { $on, $off, $emit } from './utils/gogocodeTransfer'

// 触发事件,bus 是 mitt 对象
$emit(bus, 'on-param-change', p1, p2);

// 监听事件,bus 是 mitt 对象
$on(bus, 'on-param-change', (p1, p2) {
    console.log(p1, p2);
});
  • bus.$emit 方式:注意只能传一个额外参数
import bus from './bus.js'

// 触发事件
bus.$emit('on-param-change', {p1, p2});

// 监听事件
bus.$on('on-param-change', (obj) {
    console.log(obj.p1, obj.p2);
});
  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中,官方建议使用外部的、实现了事件触发器接口的来实现事件总线的功能,而mitt是其中一个常用的选择。mitt是一个非常小巧的,只有200字节大小,并且支持全部事件的监听和批量移除。它不依赖于Vue实例,可以在不同的框架或项目中使用,例如React、Vue甚至是jQuery项目都可以使用同一个mitt来实现事件总线的功能。在使用mitt时,你需要先安装mitt(npm i mitt -s),然后可以通过mitt()创建一个mitt实例,并使用其提供的API来进行事件的绑定、触发和解绑操作。 下面是一些mitt的常用API: - `emit(name, data)`:触发事件,其中`name`是要触发的事件名称,`data`是需要传递的参数。 - `on(name, callback)`:绑定事件,其中`name`是要绑定的事件名称,`callback`是触发事件后执行的回调函数。 - `off(name)`:解绑事件,其中`name`是需要解绑的事件名称。 在Vue3中使用mitt可以参考以下步骤: 1. 首先,你需要安装mitt(npm i mitt -s)。 2. 然后,在需要使用事件总线的组件中引入mitt,例如在你的`bb.vue`组件中,你可以使用`import bus from "../utils/EventBus"`来引入mitt。 3. 在需要发出事件的地方(例如点击按钮时),可以使用`bus.emit("data", 18)`来触发名为"data"的事件,并传递参数18。 希望这个回答对你有帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值