探索前端跨组件通信:EventBus在Vue和React中的应用

本文作者系360奇舞团前端开发工程师

EventBus 简介

事件总线(Event Bus)是一种用于组件间通信的模式,通常用于解决组件之间的解耦和简化通信的问题。在前端框架中,如 Vue.js,事件总线是一个常见的概念。基本上,事件总线是一个能够触发和监听事件的机制,使得组件能够在不直接依赖彼此的情况下进行通信。事件总线可以是一个全局的单例对象,也可以是一个基于发布-订阅模式的实现。

设计模式

在软件架构中,发布/订阅Publish–subscribe pattern)是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者),而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果存在)。同样,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果存在)。6225bcfb190aca308f5ef98087fa919a.png

订阅-发布模式(Publish-Subscribe Pattern)是一种软件设计模式,也属于行为型模式之一。它定义了一种对象间一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式降低了对象之间的直接耦合,使得系统更加灵活。该模式包含两个主要角色:

  1. 发布者(Publisher): 负责发布(广播)消息或事件的对象。当发布者的状态发生变化时,它会通知所有已订阅的对象。

  2. 订阅者(Subscriber): 订阅发布者的消息或事件的对象。订阅者通过注册自己的回调函数(或观察者)来接收发布者的通知。

具体实现步骤如下:

  • 发布者维护一个订阅者列表(数组),用于存储所有订阅了它的对象。

  • 订阅者向发布者注册自己的回调函数(或观察者)。

  • 当发布者的状态发生变化时,它会遍历订阅者列表,调用每个订阅者的回调函数,通知它们状态的变化。

e5a04f50979c695cb6299c28c8887425.png
image.png

EventBus 在前端(Vue 中)的使用

  1. 创建事件总线:

javascriptCopy code
// event-bus.js

import Vue from 'vue';

// 创建一个新的Vue实例作为事件总线
const EventBus = new Vue();

// 导出该实例,以便在应用程序中的其他地方使用
export default EventBus;
  1. 组件 A:

<!-- ComponentA.vue -->

  <template>
    <div>
      <button @click="emitEvent">触发事件</button>
  </div>
  </template>

  <script>
  import EventBus from './event-bus.js';

export default {
  methods: {
    emitEvent() {
      // 使用事件总线触发名为 'custom-event' 的事件,并传递数据
      EventBus.$emit('custom-event', '这是传递的数据');
    }
  }
}
  </script>
  1. 组件 B:

<!-- ComponentB.vue -->

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

  <script>
  import EventBus from './event-bus.js';

export default {
  data() {
    return {
      eventData: ''
    };
  },
  mounted() {
    // 在组件创建时,通过事件总线监听 'custom-event' 事件
    EventBus.$on('custom-event', eventData => {
      // 更新组件的数据
      this.eventData = eventData;
      console.log('收到事件,数据为:', eventData);
    });
  }
}
  </script>

ComponentA组件通过点击按钮触发了一个名为 custom-event 的事件,并传递了一些数据。ComponentB组件在创建时通过事件总线监听了这个事件,并在事件发生时更新了组件的数据。注意:使用事件总线时需要注意组件的生命周期,确保在不再需要监听事件的组件被销毁时取消事件监听,以避免潜在的内存泄漏

  1. 销毁

beforeDestroy() {
    // 在组件销毁前取消事件监听
    EventBus.$off('custom-event', this.eventBusListener);
  }

EventBus 在前端(React 中)的使用

在 React 中,没有像 Vue 中的事件总线那样的直接内置机制。React 通常使用 props 和回调函数来实现组件之间的通信。然而,如果你的应用需要在不适用 props 传递的情况下进行全局事件的订阅和发布,可以使用第三方库,比如 eventemitter3 或者 Redux。以下是使用 Event Emitter 的一个简单示例:

  1. 安装 eventemitter3

npm install eventemitter3
  1. 创建全局的事件管理器

// eventBus.js

import { EventEmitter } from 'eventemitter3';

const eventBus = new EventEmitter();

export default eventBus;
  1. 引入这个事件总线订阅和发布事件:

// ComponentA.jsx

import React from 'react';
import eventBus from './eventBus';

class ComponentA extends React.Component {
  emitEvent = () => {
    eventBus.emit('custom-event', '这是传递的数据');
  };

  render() {
    return (
      <div>
        <button onClick={this.emitEvent}>触发事件</button>
      </div>
    );
  }
}

export default ComponentA;
// ComponentB.jsx

import React, { useState, useEffect } from 'react';
import eventBus from './eventBus';

const ComponentB = () => {
  const [eventData, setEventData] = useState('');

  useEffect(() => {
    const eventBusListener = (data) => {
      setEventData(data);
      console.log('收到事件,数据为:', data);
    };

    eventBus.on('custom-event', eventBusListener);

    return () => {
      // 在组件卸载时取消事件监听
      eventBus.off('custom-event', eventBusListener);
    };
  }, []);

  return (
    <div>
      <p>{eventData}</p>
    </div>
  );
};

export default ComponentB;
  1. 注意:在组件卸载**eventBus.off('custom-event', eventBusListener);**时取消事件监听以避免潜在的内存泄漏。

使用 EventBus 优缺点

优点:

  1. 解耦组件: 事件总线能够实现组件之间的解耦,使得它们不需要直接引用或依赖彼此,提高了代码的灵活性和可维护性。

  2. 简化通信: 对于一些简单的通信需求,事件总线提供了一种相对简单的方式,避免了通过 props 和回调函数传递数据时的繁琐操作。

  3. 全局通信: 事件总线通常是全局性的,能够在整个应用程序中的任何地方进行通信,适用于全局状态的传递和应用的整体控制。

  4. 跨组件通信: 事件总线可以方便地实现非父子组件之间的通信,而不需要在组件之间建立直接的关联。

缺点:

  1. 全局状态管理: 使用事件总线可能引入全局状态,导致应用状态变得难以追踪和理解,特别是在大型应用中。

  2. 难以调试: 全局性的事件监听和触发可能使得追踪代码执行流程和调试变得更加困难,尤其是在复杂的应用场景下。

  3. 潜在的性能问题: 大量的全局事件监听和触发可能导致性能问题,尤其是在频繁触发事件的情况下。

  4. 不明确的数据流向: 使用事件总线时,数据的流向相对不明确,可能增加代码的复杂性,使得应用程序的数据流变得更加难以理解。

  5. 安全性问题: 由于事件总线是全局的,可能存在安全风险,例如某个组件监听了不应该被其它组件触发的敏感事件。

总结

综合考虑,对于小型应用或简单的场景,事件总线是一个方便的工具。但在大型应用或需要更严格状态管理和调试的情况下,可能需要考虑使用更复杂的状态管理工具,如 Vuex 或 Redux。使用事件总线时,需要谨慎使用,避免滥用全局状态和事件。

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

27c5773aba61ff4440a0036d14d3d185.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【hcie-cloud】【21】容器详解【容器网络说明、容器存储说明、容器镜像说明、dockerfile详述、缩略词】【下】

文章目录 容器介绍&#xff0c;容器工作机制、容器常用命令说明容器网络容器网络简介容器常用网络类型 - Bridge容器常用网络类型 - Host容器常用网络类型 - None其他容器网络类型【Macvlan、Overlay、IPvlan】容器网络相关配置 容器存储容器中应用数据的存储容器持久化存储配置…

HTML5 article标签,<time>...</time>标签和pubdate属性的运用

1、<article>...</article>标签的运用 article标签代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。它可以是一篇博客或报竟杂志中的文章、一篇论坛帖子、一段用户评论或一个独立的插件&#xff0c;或者其他任何独立的内容。把文章正文放在h…

【HarmonyOS4.0】第四篇-ArkUI基础实战

一、ArkUI框架简介 ArkUI开发框架是方舟开发框架的简称&#xff0c;它是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架&#xff0c;它使用极简的UI信息语法、丰富的UI组件以及实时界面语言工具&#xff0c;帮助开发者提升应用界面开发效率 30%&#xff0c;开发…

(23)Linux的软硬连接

前言&#xff1a;上一章我们讲解了 inode&#xff0c;为文件系统收了尾&#xff0c;这几章我们充分地讲解完了文件系统的知识点&#xff0c;现在我们开始开始学习软硬链接了。 软硬链接 1、Linux 下的快捷方式&#xff1a;软链接 上一章我们介绍完了 inode &#xff0c;我们…

试用统信服务器操作系统UOS 20

作者&#xff1a;田逸&#xff08;formyz&#xff09; 试用统信Linux操作系统UOS&#xff0c;想了解一下用已有的Linux经验能否轻松驾驭它。以便在某些场景下&#xff0c;可以多一种选择。本次试验在Proxmox VE 8&#xff08;以下简称PVE 8&#xff09;平台下进行&#xff0c;采…

【题解】—— LeetCode一周小结

1.经营摩天轮的最大利润 题目链接&#xff1a; 1599. 经营摩天轮的最大利润 你正在经营一座摩天轮&#xff0c;该摩天轮共有 4 个座舱 &#xff0c;每个座舱 最多可以容纳 4 位游客 。你可以 逆时针 轮转座舱&#xff0c;但每次轮转都需要支付一定的运行成本 runningCost 。摩…

JRT打印元素绘制协议之-A4Double

以前打印相信很多人因为A4打印两个报告头大过&#xff0c;M要把一堆报告既有A4的也有A5的还有微生物的&#xff0c;可能输出Page还不那么严谨。要么换页不对叠加了、要么多空白页、中间夹杂A4报告就更加头大。也有的人为了打印页码的共几页而头大。 借助新设计的优势&#xff…

uni-app中轮播图实现大图预览

参考效果 当轮播图滑动切换的时候更新自定义下标&#xff0c;当图片被点击的时候大图预览。 参考代码 商品详情页轮播图交互 <script setup lang"ts"> // 轮播图变化时 const currentIndex ref(0) const onChange: UniHelper.SwiperOnChange (ev) > …

TAX税类小知识

历史及发展 我国作为流转税为主国家&#xff0c;目前经历3类税制&#xff1a;统收统付--包干制---分税制&#xff0c; 分别对应时间为建国--改革开放--93年朱提出分税延续至今&#xff1b; 未来趋势必然是完善所得税。 ps:流转税是间接税&#xff0c;间接转嫁给消费者&#…

TypeScript基础

ts学习 目录概述需求&#xff1a; 设计思路实现思路分析1.TypeScript 基础类型2.TypeScript 变量声明3.TypeScript 接口4.TypeScript 类5.TypeScript 函数5.TypeScript 泛型5.TypeScript 枚举TypeScript 类型推论TypeScript 类型兼容性TypeScript 高级类型TypeScript 迭代器和生…

深度解析Dubbo的基本应用与高级应用:负载均衡、服务超时、集群容错、服务降级、本地存根、本地伪装、参数回调等关键技术详解

负载均衡 官网地址&#xff1a; http://dubbo.apache.org/zh/docs/v2.7/user/examples/loadbalance/ 如果在消费端和服务端都配置了负载均衡策略&#xff0c; 以消费端为准。 这其中比较难理解的就是最少活跃调用数是如何进行统计的&#xff1f; 讲道理&#xff0c; 最少活跃数…

金和OA C6 upload_json 任意文件上传漏洞

产品介绍 金和网络是专业信息化服务商,为城市监管部门提供了互联网监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。 漏洞概述 金和 OA C6 upload_json接口处存在任意文件上传漏洞&#xff0c;攻击者可以通过构造特殊请求包上…

视频号小店新手该怎么运营?团队实操经验分享!

我是电商珠珠 视频号小店作为一个新兴平台&#xff0c;自然预示着有更多的机会在。 所以有很多新手想要了解这个平台并进行入驻&#xff0c;但是却不知道该怎么去运营&#xff0c;没有货源怎么办。 今天我就来给大家详细的讲一下。 一、入驻 入驻的话需要一张企业的营业执…

阿里巴巴秋招前端笔试题

单选题 下面的 JSX 代码中&#xff0c;哪一个无法达到预期的效果&#xff1f; A.<h2>Hello World</h2> B.<input type”checkbox”/> C.<div class”msg-box”>{msg}</div> D.<label htmlFor”name”>Leo</label> E.div styl…

人工智能_机器学习091_使用三维瑞士卷数据_KMeans聚类算法进行瑞士卷数据聚类---人工智能工作笔记0131

然后我们首先来构建一下数据 准备瑞士卷数据: import numpy as np 导入数学计算包 import matplotlib.pyplot as plt 导入画图包 #自底向上聚类 from sklearn.cluster import AgglceerativeClustering 导入分层聚类模型 from sklearn.datasets import make_swiss_roll # 瑞士卷…

“五岳杯”2023量子计算挑战赛启动仪式在南方科技大学成功举办

​2023年11月4日下午&#xff0c;由北京图象图形学学会、中国移动云能力中心&#xff08;以下简称“移动云”&#xff09;主办&#xff0c;南方科技大学承办&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;协办的“五岳杯”2023量子计算挑战…

RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词&#xff1a;SFUD,FLASH,W25Q64&#xff0c;W25Q128&#xff0c;STM32F407 说明&#xff1a;RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64&#xff0c;通过 STM32CubeMX 配置 STM32 SPI 驱动。 提示&#xff1a;SFUD添加后的存储位置 1.打开RT-Thread Sett…

OpenGL学习笔记-Blending

混合方程中&#xff0c;Csource是片段着色器输出的颜色向量&#xff08;the color output of the fragment shader&#xff09;&#xff0c;其权重为Fsource。Cdestination是当前存储在color buffer中的颜色向量&#xff08;the color vector that is currently stored in the …

ROS2 Humble学习笔记

本文发表与个人的github pages。部分内容未同步到这里。 想查看完整内容&#xff0c;请移步到ROS2 Humble学习笔记。 一、前言 2013年的时候已经接触ROS了&#xff0c;当时断断续续学习了一些ROS的基础知识。16年搬到深圳之后&#xff0c;也有幸参加过星火的一次关于ROS的一些…

S281 LoRa网关在智能电力监测系统中的应用

随着能源消耗的增加和环境保护的要求&#xff0c;智能电力监测系统在电力行业得到了广泛的应用。作为一家领先的科技公司&#xff0c;钡铼技术有限公司推出的S281 LoRa网关为智能电力监测系统提供了强大的支持和解决方案。本文将重点介绍S281 LoRa网关在智能电力监测系统中的应…