《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
    评论
在Uniapp中使用Vue3的事件总线bus),可以通过创建一个空的Vue实例来实现。首先,在你的项目中创建一个bus.js文件,并在其中导出一个空的Vue实例。代码如下所示: ```javascript // bus.js import { createApp } from 'vue' const app = createApp({}) export default app ``` 然后,在需要使用事件总线的组件中,可以通过导入bus.js并使用该实例来发送和接收事件。例如,发送事件的组件可以使用`app.config.globalProperties.$bus`来访问bus实例,并使用`$emit`方法发送事件。接收事件的组件可以使用`$on`方法监听事件。 ```javascript // 发送事件的组件 import { getCurrentInstance } from 'vue' import app from '@/bus' export default { methods: { sendEvent() { app.config.globalProperties.$bus.emit('event', data) } } } // 接收事件的组件 import { getCurrentInstance } from 'vue' import app from '@/bus' export default { mounted() { app.config.globalProperties.$bus.on('event', this.handleEvent) }, methods: { handleEvent(data) { // 处理事件 } } } ``` 这样,你就可以在Vue3的Uniapp项目中使用事件总线了。注意,由于Vue3的语法和Vue2有所不同,所以之前提到的一些方法可能无法直接使用。但是通过创建一个空的Vue实例来实现事件总线是一个常用的解决方案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [使用Vue3做uniapp项目,如何在下一个页面使用eventChannel](https://blog.csdn.net/weixin_46683645/article/details/127277600)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值