聊一聊如何在Vue中使用事件总线( Event Bus)进行组件间通信

news2024/11/18 15:23:10

d0cbb511dca99165271893f026d16d9a.jpeg

事件总线模式允许不同的组件之间进行通信。它要求一个中央枢纽,组件可以通过它发送和接收事件,从而使组件之间的数据交换和交互更加顺畅。本文探讨了它的使用方法,以便开发人员能够充分利用它在Vue开发中的潜力。

跨通信是应用程序中组件之间的交互。这有助于应用程序的不同部分之间的顺畅协作。其重要性体现在以下几个方面:

  • 数据共享:跨组件通信确保组件之间的数据高效交换。

  • 处理事件:它帮助它们更新状态并触发必要的事件。它确保组件对事件做出相应的反应。

  • 简化开发和可重用性:当组件互相交互时,它们可以独立工作。因此,管理代码并在整个应用程序中重用组件变得更加容易。

  • 提升用户体验:有效的沟通有助于流畅而互动的用户体验。

  • 可扩展性:跨组件通信帮助开发人员管理他们的应用程序。它将应用程序拆分为更小、可管理的部分。随着时间的推移,这种可扩展性对于应用程序的演进和扩展至关重要。

Vue中事件总线的概述

Vue中的事件总线是一种类似于信使的机制,用于帮助组件之间进行通信。就像朋友之间互发消息一样,即使彼此不认识也能进行交流。通过全局事件总线,组件可以在没有紧密连接的情况下进行交互,这使得它具有灵活性和高效性。你可以设置事件总线,然后在需要的时候组件可以发出事件。其他组件可以监听这些事件并做出相应的反应。它有助于保持代码的组织性,并促进Vue应用中组件之间的协作。

事件总线具有一些方法,用于促进组件间的交互通信。它们包括:$on(eventName, callback) 监听事件, $emit(eventName, data) 触发带有可选数据负载的事件,以及 $off(eventName, callback) 移除事件监听器。在Vue中, $once 方法是另一个事件总线方法,允许组件仅监听一次事件。它的功能类似于 $on 方法,但不同之处在于在事件触发一次后自动移除事件监听器。

搭建一个Vue项目

我们将从创建一个Vue应用程序开始,然后继续设置事件总线以进行跨组件通信。

接下来,在目录中运行以下命令来创建一个新的Vue项目。

npm create vue@latest

按照向导的指示,根据项目需求选择适合你的设置的正确工具。

bb175f8712a6bf82bc9d2b276643d170.jpeg

一旦设置完成,通过运行以下命令进入项目目录:

cd eventBus-app

npm install

npm run dev

现在,您可以运行开发服务器来查看您的Vue应用程序的运行情况,打开你的浏览器,访问提供的本地开发URL:http://127.0.0.1:5173/

设置事件总线

在Vue中,设置事件总线是一个简单的过程,允许组件之间进行通信而无需直接依赖。

要创建事件总线实例,我们首先定义一个专门处理事件的新Vue实例。这可以在一个单独的JavaScript文件或主Vue应用程序文件中完成。

首先,由于我们正在使用Vue 3,我们必须更新事件总线设置,以使用mitt库进行事件处理:

打开终端并使用以下命令安装mitt库:

npm install mitt

或者

yarn add mitt

接下来,在src文件夹中创建一个名为 eventBus.js 的单独的js文件。

// eventBus.js file for Vue3

import mitt from 'mitt';

// Create a new event bus using mitt
const Event Bus = mitt();

export default eventBus;

通过导入Vue并创建一个新实例,我们现在拥有了一个事件总线,可以方便组件之间的通信。

注意:如果您使用的是Vue 2,不需要使用mitt库;您可以按照下面的配置继续进行:eventBus.js

// eventBus.js file for Vue2

import Vue from 'vue';

// Create a new Vue instance to act as the Event Bus
const eventBus = new Vue();

export default eventBus;

发出和监听事件

一旦事件总线实例设置完成,组件就可以开始发出事件并监听它们。组件使用Vue中可用的 $emit 方法来发出事件。该方法的第一个参数是事件名称,第二个参数是可选的负载,如果需要传递数据与事件一起使用。

// ComponentA.vue

<template>
 <div>
   <button @click="handleClick">Say Hello</button>
 </div>
</template>

<script setup>
import eventBus from "../eventBus";

const handleClick = () => {
 // Emitting an event with the name 'sayHello'
 eventBus.emit("sayHello", "Hello from Component A!");
};
</script>

在接收端,其他组件可以监听发出的事件,并在事件发生时执行相应的操作。这是通过使用 $on 方法实现的,该方法监听特定的事件名称。

// ComponentB.vue

<template>
 <div>
   <p>{{ message }}</p>
 </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import eventBus from "../eventBus";

const message = ref("")

onMounted(() => {
 // Listening for the 'sayHello' event from the 'eventBus'
 eventBus.on("sayHello", (data) => {
   // Handling the event and accessing the payload data
   message.value = data
 });
});
</script>

使用事件总线传递数据

使用事件总线传递数据涉及到事件负载的使用和复杂数据结构的共享。让我们通过代码示例来说明这些概念:

使用事件负载(Event Payloads)

事件负载允许组件在发出事件时传递附加数据。当从一个组件向另一个组件发送特定信息时,这非常有用。上面的示例中已经说明了这个工作原理。发射器 ComponentA 发出一个带有负载为“Hello from Component A!”的 sayHello 事件。监听器 ComponentB 监听该事件,并使用事件发送的负载更新其 message 值。这基本上就是事件负载的工作原理。

共享复杂数据结构

事件总线还可以在组件之间共享更复杂的数据结构,例如对象或数组。这使得组件可以交换结构化数据,而无需紧密耦合。以下是共享复杂数据结构的示例:

让我们更新我们的初始组件A(发射器),使用更复杂的有效载荷数据。

// ComponentA

<template>
 <div>
   <button @click="fetchUserDetail">Fetch User</button>
 </div>
</template>

<script setup>
import { reactive, ref } from "vue";
import eventBus from "../eventBus";

const userDetails = reactive({
 name: "Hannah",
 dob: "23-Nov",
 favColor: "Gray",
});

const fetchUserDetail = () => {
 eventBus.emit("getUserDetails", userDetails);
};
</script>

接收组件(监听器)实现了一个事件处理程序并访问共享数据是:

// ComponentB

<template>
 <div>
   <p>{{ user.name }}</p>
   <p>{{ user.dob }}</p>
   <p>{{ user.favColor }}</p>
 </div>
</template>

<script setup>
import { onMounted, reactive, ref } from "vue";
import eventBus from "../eventBus";

const user = ref({})

onMounted(() => {
 eventBus.on("getUserDetails", (userData) => {
   user.value = userData
 });
});
</script>

最佳实践和技巧

保持事件名称一致性:保持事件名称一致性至关重要,以确保清晰明了,避免混淆。通过使用有意义且描述性的事件名称,您可以轻松识别每个事件的目的及其相应的功能。例如,上述使用了 sayHello 和 getUserDetails ,它们具有自我描述性,人们可以轻松说明它们的功能。

处理异步事件:在处理事件总线中的异步操作时,适当地处理它们非常重要。例如,如果一个事件涉及数据获取或API调用,请使用async/await或Promises来有效地管理异步代码流程。

// emitter

onMounted(async () => {
 const data = await fetchData(); // Some asynchronous data fetching function
 eventBus.emit("data-fetched", data);
});
// listener  

onMounted(() => {
 eventBus.on("data-fetched", async (data) => {
   // Handle the asynchronously received data here
   await processData(data); // Some asynchronous data processing function
 });
});

避免事件冲突:当两个或多个组件使用相同的事件名称时,可能会发生事件冲突。这可能导致意外的行为或冲突。为了避免这种情况,可以根据组件名称或特定目的对事件进行命名空间划分。

// In Component A

<script setup>
import eventBus from "../eventBus";

const handleClick = () => {
 // Emitting an event with the name 'sayHello'
 eventBus.emit("componentA-sayHello", "Hello from Component A!");
};
</script>
// In Component B

onMounted(() => {
   eventBus.on('componentA-sayHello', (data) => {
     message.value = data;
   });
 }

通过在事件名称前加上特定组件的标识符,可以最大程度地减少事件冲突的风险。

事件总线与Props相比

事件总线和Props是Vue中常用的两种组件间通信的方法。让我们来探索它们的区别。

事件总线

事件总线允许不直接相关的组件之间进行通信,无需通过父组件传递数据。它作为一个中央事件中心,用于发射和监听自定义事件。

示例

在A组件中:

<template>
 <button @click="send">Emit Event</button>
</template>


<script setup>
import eventBus from "../eventBus";
import {ref } from "vue";

const send = () => {
 eventBus.emit('sendFile', { message: 'File Sent' });
},
</script>

在B组件中:

<template>
 <div>
   <p>{{ message }}</p>
 </div>
</template>

<script setup>
import eventBus from "../eventBus";
import { onMounted, ref } from "vue";

const message = ref("")

onMounted(()=> {
   eventBus.on('custom-event', (data) => {
     message.value = data.message;
   })
}),
</script>

Props(属性)

Props涉及通过属性将数据从父组件传递给子组件。

示例:

在ParentComponent中:

// Parent Component

<template>
 <child-component :message="message" />
</template>

<script setup>
import ChildComponent from './ChildComponent';
import { ref } from "vue";

const message = ref("Happy Holidays")
</script>

在ChildComponent中:

<template>
 <div>
   <p>{{ message }}</p>
 </div>
</template>

<script setup>
defineProps({
 message: {
   type: String,
   required: true
 }
})
</script>

比较事件总线与Vuex

事件总线和Vuex在范围和用例上有所不同。事件总线适用于局部通信,而Vuex是一个用于在多个组件之间共享全局数据的状态管理解决方案。

事件总线(本地通信):

上面已经演示了事件总线的示例。当只有少数组件需要通信且数据交换不复杂时,它是合适的。

Vuex(全局状态管理):

Vuex 允许集中式状态管理,这意味着数据可以在整个应用程序中被多个组件共享和访问。

示例

在 store.js (Vuex设置)中:

import { createStore } from 'vuex';

export default createStore({
   state() {
       return {
           message: 'Hello from Vuex store',
       };
   },
   mutations: {
       setMsg: (state, msg) => state.message = msg
   },
   actions: {},
   getters: {
       getMsg: (state) => state.message,
   },
});

在A组件中:

<template>
 <div>
   <p>{{ message }}</p>
 </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { useStore } from 'vuex';

const store = useStore();

const message = computed(() => {
 return store.getters['getMsg'];
});
</script>

<style></style>

在B组件中:

<template>
 <div>
   <button @click="updateMsg">Update Message</button>
 </div>
</template>

<script setup>
import { useStore } from "vuex";

const store = useStore();

const updateMsg = () => {
 store.commit("setMsg", "Hello World");
};
</script>

事件总线和Vuex都有各自的优势,应根据应用程序的具体通信需求来选择。事件总线适用于简单和局部化的通信,而Vuex则推荐用于管理跨多个组件的复杂全局状态。

结束

Vue中的事件总线促进了高效的跨组件通信,增强了模块化和可重用性。它的好处包括简化的数据共享、灵活性和可维护性。通过遵循最佳实践,开发人员可以确保有组织的事件系统和顺畅的通信。事件总线赋予了Vue应用程序强大的能力,简化了开发过程,丰富了用户体验。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1120915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter如何测试websocket接口?

jmeter做接口测试&#xff0c;很多人都是做http协议的接口&#xff0c;就有很多人问websocket的接口怎么测试啊&#xff1f; 首先&#xff0c;我们要明白&#xff0c;websocket接口是什么接口。 然后&#xff0c;我们怎么用jmeter测试&#xff1f; jmeter要测试websocket接口…

B/S医院手术麻醉临床系统:围术期的认识

手术是治疗很多疾病最有效而且绕不开的措施。而从医生和患者确定了要进行手术治疗的时候&#xff0c;医院相关人员就会开始围着患者团团转&#xff0c;在术前、术中和术后&#xff0c;医生会告诉患者很多事情&#xff0c;患者也会了解很多就诊相关知识。 一、围术期的认识 围术…

qml之动态元素类型

文章目录 动画例子 应用动画例子 缓动曲线例子 动画分组例子 嵌套动画代码 状态和转换代码 动画 QMlL使用插值的方式控制属性的更改。动画是在指定的时间内一些列属性的持续变化。 常用的动画类型元素动画&#xff1a;PropertyAnimation:属性值改变播放动画NumberAnimation:qr…

【快速解决】在vs2022中配置SFML图形库

目录 SFML 图形库的安装步骤如下&#xff1a; 1.下载 SFML 在 SFML 的官网&#xff08;下载对应操作系统版本的 SFML&#xff09;。​编辑 2.解压文件 将下载的压缩包解压至任意位置&#xff0c;得到类似如下的目录结构&#xff1a; 3.配置 VS 打开 Visual Studio&#xff…

Linux ————使用常用的Linux命令

&#xff08;一&#xff09;Linux命令的特点 在Linux系统的早期版本中&#xff0c;由于不支持图形用户界面&#xff0c;命令行成为了主要的操作手段。对于那些在文本模式和终端模式下需要查看系统状态和监控系统操作的用户&#xff0c;熟悉常用的Linux命令是至关重要的。以下是…

自然语言处理---Transformer机制详解之Self attention机制详解

1 Self-attention的特点 self-attention是一种通过自身和自身进行关联的attention机制, 从而得到更好的representation来表达自身. self-attention是attention机制的一种特殊情况&#xff0c;在self-attention中, QKV, 序列中的每个单词(token)都和该序列中的其他所有单词(to…

RDB.js:适用于 Node.js 和 Typescript 的终极对象关系映射器

RDB.js 是适用于 Node.js 和 Typescript 的终极对象关系映射器&#xff0c;可与 Postgres、MS SQL、MySQL、Sybase SAP 和 SQLite 等流行数据库无缝集成。无论您是使用 TypeScript 还是 JavaScript&#xff08;包括 CommonJS 和 ECMAScript&#xff09;构建应用程序&#xff0c…

高效MMdetection(3.1.0)环境安装和训练自己数据集教程(实现于Linux(ubuntu),可在windows尝试)

很久没用mmdetection了&#xff0c;作为目标检测常见的几个深度学习框架&#xff0c;mmdetection用的人还是很多的&#xff0c;其中比较吸引人的一点就是mmdetection集成了非常多的算法&#xff0c;对于想做实验对比和算法学习的人来说&#xff0c;基于这个框架可以事半功倍。因…

“暂停加息,股市低迷:242只股票创新低,比特币突破2.8万美元后看涨趋势不可挡!“

11 月1日 FOMC 会议 美联储主席杰罗姆鲍威尔周五在纽约发表讲话&#xff0c;毫不意外地&#xff0c;他采取了更加鸽派的立场&#xff0c;因为在不确定的世界中&#xff0c;美国政府的过度杠杆化和可能即将到来的经济衰退已成为共识。 根据鲍威尔对未来加息的最低限度讨论&…

Datawhale学习笔记AI +新能源:电动汽车充电站充电量预测2

在飞浆平台上成功运行出pandas-profiling啦~ 首先一键安装 pip install ydata_profiling然后演示&#xff0c;可以生成一个网页对数据有一个比较好的理解 import numpy as np import pandas as pd from ydata_profiling import ProfileReporttrain_power pd.read_csv(/home/…

【神印王座】半神级别的伊莱克斯,有着什么故事,他又为何会陨落?

【侵权联系删除】【文/郑尔巴金】 你知道手握日月摘星辰&#xff0c;世间无我这般人&#xff0c;如果我想我早已成神&#xff0c;这背后到底藏着一个什么样的故事吗&#xff1f;伊莱克斯一个配角&#xff0c;为何能让人如此痴迷&#xff1f;在最近的国漫场里&#xff0c;有两部…

Windows Server 2019 搭建FTP站点

目录 1.添加IIS及FTP服务角色 2.创建FTP账户&#xff08;用户名和密码&#xff09;和组 3.设置共享文件夹的权限 4.添加及设置FTP站点 5.配置FTP防火墙支持 6.配置安全组策略 7.客户端测试 踩过的坑说明&#xff1a; 1.添加IIS及FTP服务角色 a.选择【开始】→【服务器…

【刷题篇】反转链表

文章目录 一、206.反转链表二、92.反转链表 ||三、25. K 个一组翻转链表 一、206.反转链表 class Solution { public://使用头插//三个指针也可以ListNode* reverseList(ListNode* head) {if(headnullptr)return nullptr;ListNode* curhead;ListNode* newheadnew ListNode(0);L…

推荐一款简单好用的Bug管理软件

软件开发的速度和质量是企业成功的关键因素&#xff0c;然而随着软件项目的复杂性增加&#xff0c;Bug的管理变得越来越困难。为了解决这个问题&#xff0c;Zoho公司推出了一款强大的Bug管理软件&#xff0c;帮助企业在一个地方记录和跟踪Bug&#xff0c;提高修复效率。 这款名…

spring tx:advice事务配置—— tx:advice中不允许出现属性 ‘transaction-manager‘

今天在配置java事务管理时出现了一些问题。 提示&#xff1a;只有这几个属性 经过查询资料发现是bean的配置少了一些。 可以在xml文件顶部添加&#xff1a; xmlns:tx"http://www.springframework.org/schema/tx" 下面也提供一份bean文件配置的模板&#xff1a; &a…

MongoDB URL链接 如何设置账号密码

个人博客&#xff0c;求关注。。 MongoDB URL链接 如何设置账号密码 假设你的账号是root&#xff0c;你的密码也是root&#xff0c;则 mongodb://username:passwordlocalhost:27017完美&#xff0c;再见。

《红蓝攻防对抗实战》二.内网探测协议出网之TCP/UDP协议探测出网

目录 一.TCP/UDP协议探测出网 1.NC工具探测TCP协议出网 2.Telnet命令探测TCP协议出网 3.UDP协议探测出网 当红队人员在进行内网渗透时&#xff0c;经常会遇到目标主机不出网的场景&#xff0c;而主机不出网的原因有很多&#xff0c;常见的原因例如目标主机未设置网关&#…

Linux环境部署应用必知必会

修改环境变量 Linux环境变量配置的6种方法&#xff0c;建议收藏&#xff01; - 知乎 修改java环境变量 软件安装 安装redis redis是一个非关系型数据库&#xff0c;是一个存储键值对的数据库&#xff0c;通常被称为数据结构服务器。 值&#xff08;value&#xff09;可以是…

00TD时尚女童睡衣,蕾丝边+蝴蝶结太好看了

甜美又可爱的蕾丝花边加蝴蝶结 真的一下子戳中了我的心巴&#xff0c; 满满的少女风真的很好看&#xff0c; 妥妥的可爱小公主一枚 柔软又亲肤&#xff0c;厚厚的很保暖 睡觉真的很舒服 还有袖口和裤脚都做了松紧设计哟&#xff01;

【iOS】UITableView总结(Cell的复用原理、自定义Cell、UITableViewCell协议方法)

UITableView 列表的特点&#xff1a; 数据量大样式较为统一通常需要分组垂直滚动通常可视区只有一个 -> 视图的复用 UITableViewDataSource UITableView作为视图&#xff0c;只负责展示&#xff0c;协助管理&#xff0c;不管理数据 需要开发者为UITableView提供展示所需…