Event Bus实现兄弟组件通信

news2024/10/16 16:20:58

Event Bus实现兄弟组件通信

Event Bus(事件总线)是一种组件间通信的模式,主要用于非父子关系的组件之间的通信。它通过创建一个全局的 Vue 实例作为事件中心,任何组件都可以通过这个中心来触发事件或监听事件,从而实现跨组件的数据传递和状态同步。

实现原理:

  • 创建全局事件总线: 创建一个单独的 Vue 实例作为事件总线,用于在不同组件之间传递消息。

  • 发送事件: 在一个组件中触发事件,通过 EventBus.$emit 方法发送事件和数据。

  • 接收事件: 在另一个组件中监听事件,通过 EventBus.$onEventBus.$once 方法接收事件和数据。

  • 清理事件监听器: 组件销毁时,移除事件监听器,避免内存泄漏。

优点
  • 解耦: 组件之间不需要直接引用彼此,提高了组件的独立性和可复用性。

  • 灵活性: 可以方便地扩展事件和数据传递,适用于复杂的多组件通信场景。

  • 易于维护: 事件总线模式使得组件之间的通信更加清晰,便于维护和调试。

缺点
  • 命名冲突: 如果多个组件使用相同的事件名称,可能会导致命名冲突。

  • 调试困难: 由于事件总线中的事件传递路径不明确,调试时可能较难追踪问题所在。

  • 性能开销: 频繁触发事件可能导致性能开销增加,尤其是在大型应用中。

  • 状态管理复杂: 对于更复杂的状态管理,使用 Vuex 可能更为合适,特别是当组件间的通信变得更加复杂时。

代码示例

vue2.x 使用

创建全局事件总线:

// main.js

import Vue from "vue";
import App from "./App";
import store from "./store";
import router from "./router";

new Vue({
  el: "#app",
  router,
  store,
  beforeCreate() {
    Vue.prototype.$bus = this;
  },
  render: (h) => h(App),
});

parent.vue (父组件)

// parent.vue

<template>
  <div class="parent">
    <h2>父组件</h2>
    <div class="box">
      <first-son />
      <second-son />
    </div>
  </div>
</template>

<script>
import firstSon from './firstSon.vue';
import secondSon from './secondSon.vue';
export default {
  name: 'parent',
  data() {
    return {

    }
  },
  components: { firstSon, secondSon },
  methods: {

  }
}
</script>

firstSon.vue (子组件1)

// firstSon.vue

<template>
  <div class="son">
    <h2>子组件1</h2>
    <el-button type="primary" @click="sendMessage">发送消息</el-button>
  </div>
</template>

<script>
export default {
  name: 'firstSon',
  data() {
    return {
      msg: 'Hello from brother component!'
    }
  },
  methods: {
    sendMessage(){
      this.$bus.$emit('sendBrotherMsg', this.msg);
    }
  }
}
</script>

secondSon.vue (子组件2)

// secondSon.vue

<template>
  <div class="grandpa">
    <h2>子组件2</h2>
    <div>{{ msg }}</div>
  </div>
</template>

<script>
export default {
  name: 'secondSon',
  data() {
    return {
      msg: '',
    }
  },
  created() {
    this.getSendMessage();
  },
  beforeDestroy() {
      // 清理事件监听器
    this.$bus.$off('sendBrotherMsg')
  },
  methods: {
    getSendMessage() {
        // 添加事件监听器接受兄弟组件传过来的数据
      this.$bus.$on('sendBrotherMsg', msg => {
        console.log('msg::: ', msg);
        this.msg = msg;
      })
    }
  }
}
</script>

上述示例中:

  • parent.vue 组件为父组件,导入 firstSon.vuesecondSon.vue 组件。

  • firstSon.vue 组件点击按钮触发事件 this.$bus.$emit() 方法发送 sendBrotherMsg 事件和 this.msg 参数。

  • secondSon.vue 组件通过 this.$bus.on() 接收 sendBrotherMsg 事件和 msg 参数,并在 cerated 生命周期执行调用。

vue3.x使用

在 Vue 3.x 中,虽然不再推荐使用全局的 Vue 实例作为事件总线(因为 Vue 3 已经移除了全局 Vue 构造函数),但我们仍然可以使用类似的模式来实现兄弟组件间的通信。通常我们会创建一个普通的 JavaScript 模块来充当事件总线的角色。下面是如何在 Vue 3 中实现这一点的示例。

创建事件总线模块

首先,我们需要创建一个事件总线模块,它可以是一个简单的 JavaScript 对象,用来存储事件监听器,并提供 onemit 方法来监听和触发事件。

// eventBus.js

export const EventBus = {
  listeners: {} as Record<string, Function[]>,

  $on(event: string, callback: (...args: any[]) => void): void {
    if (!this.listeners[event]) {
      this.listeners[event] = [];
    }
    this.listeners[event].push(callback);
  },

  $emit(event: string, ...args: any[]): void {
    const callbacks = this.listeners[event];
    if (callbacks) {
      callbacks.forEach(callback => callback(...args));
    }
  },

  $off(event: string, callback: (...args: any[]) => void): void {
    const callbacks = this.listeners[event];
    if (callbacks) {
      this.listeners[event] = callbacks.filter(cb => cb !== callback);
    }
  }
};

parent.vue (父组件)

// parent.vue

<template>
  <div class="parent">
    <h2>父组件</h2>
    <div class="box">
      <firstSon />
      <secondSon />
    </div>

  </div>
</template>

<script setup lang="ts" name="parent">
import firstSon from './firstSon.vue';
import secondSon from './secondSon.vue';
</script>

firstSon.vue (子组件1)

// firstSon.vue

<template>
  <div class="firstSon">
    <h2>子组件1</h2>
    <el-button type="primary" @click="sendMessage">发送消息</el-button>
  </div>
</template>

<script setup lang="ts" name="firstSon">
import { EventBus } from './eventBus.ts';

function sendMessage() {
  const data = { key: 'value' };
  EventBus.$emit('sendBrotherMsg', data);
}
</script>

secondSon.vue (子组件2)

// secondSon.vue

<template>
  <div class="secondSon">
    <h2>子组件2</h2>
    <div>{{ receivedMessage }}</div>
  </div>
</template>

<script setup lang="ts" name="secondSon">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { EventBus } from './eventBus';

const receivedMessage = ref('');

onMounted(() => {
  // 监听事件
  EventBus.$on('sendBrotherMsg', handleData);
});

onBeforeUnmount(() => {
  EventBus.$off('sendBrotherMsg', handleData);
});

// 接受参数
const handleData = (data: { key: string }) => {
  console.log('data::: ', data);
  receivedMessage.value = data.key;
};
</script>

通过上述示例,我们可以看到:

  • 创建事件总线:使用一个简单的 TypeScript 对象作为事件总线。
  • 触发事件:在组件 firstSon.vue 中通过 EventBus.$emit 方法触发事件,并传递数据。
  • 监听事件:在组件 secondSon.vue 中通过 onMounted 生命周期钩子添加事件监听器,并通过 handleData 函数处理接收到的数据。
  • 清理事件监听器:在组件销毁之前,通过 onBeforeUnmount 生命周期钩子移除事件监听器,防止内存泄漏。

总结

Event Bus 是 Vue 中一种常用的组件间通信模式,它利用全局的 Vue 实例作为事件中心,允许组件之间通过触发和监听事件来进行通信。这种模式简单易用,适用于简单的跨组件通信场景。然而,在更复杂的项目中,可能需要考虑使用 Vuex 进行状态管理,以更好地组织和管理全局状态

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

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

相关文章

vscode---snippets配置全局代码片段,快捷开发!

代码片段的作用&#xff1a;在开发一个项目时&#xff0c;经常会遇到好多同一个代码逻辑&#xff0c;可配置固顶逻辑的代码块&#xff0c;避免重复敲同一代码&#xff1b; 举例&#xff1a;比如跳转登录&#xff0c;需要调用app的客户端方法&#xff0c;api调用跳转&#xff1…

Web 原生组件化方案:Web Components

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Web 组件化是一种将Web应用的UI部分拆分成可复用的独立组件的架构方法。这种方法有助于提高代码的可维护性、可重用性和可测试性。 而Web Components 标准则提供了一套原生的API&#xff0c;允许开发者创建…

TestCraft - GPT支持的测试想法生成器和自动化测试生成器

在当今快速变化的软件开发世界中&#xff0c;自动化测试已成为确保软件质量的关键环节。而随着AI技术的进步&#xff0c;越来越多的工具开始引入人工智能&#xff0c;来辅助生成测试用例和自动化测试脚本。其中&#xff0c;TestCraft&#xff0c;作为一款GPT支持的测试想法生成…

天命所归,SyntaxFlow助大圣取得真经

之前预告许久的SyntaxFlow功能已经登陆Yakit&#xff01; SyntaxFlow代码查询需要先进行项目编译。 手动编译 在前端的YakRunner界面&#xff0c;主界面或选项栏可以直接点击“编译项目”功能。 可见图中红色方框圈起的选项 编译项目的选项如下&#xff1a;必选项为项目名、…

工控机防病毒/防勒索病毒如何一步搞定?

随着勒索病毒的肆虐和内部运营泄密事件的频发&#xff0c;企业数据安全正面临着前所未有的挑战。苏州深信达网络科技有限公司&#xff0c;作为数据安全解决方案的先驱&#xff0c;推出了MCK主机加固解决方案&#xff0c;为企业数据安全提供了一道坚不可摧的防线。 MCK主机加固…

Linux:多路转接 select、poll、epoll

目录 1&#xff1a;select 1. 参数解释 2. 函数返回值 3. fd_set 4. fd_set 相关接口 5. timeval 5. 常见使用 6. 理解 select 执行过程 7. select 的特点 8. select 缺点 9. select 应用 2&#xff1a;socket 就绪条件 1. 读事件就绪&#xff08;Readable&#x…

智能优化算法-海马优化算法(SHO)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 海马优化算法 (Seahorse Optimization Algorithm, SHO) 是一种基于群体智能的元启发式优化算法&#xff0c;它模拟了海马的觅食行为、繁殖行为以及社会互动&#xff0c;用于解决复杂的优化问题。 SHO的工作机制…

精选干货!分享5款ai智能写论文软件

在当今信息爆炸的时代&#xff0c;AI智能写作工具已经成为我们写作过程中的得力助手。特别是对于学术论文的撰写&#xff0c;这些工具不仅能够提高写作效率&#xff0c;还能帮助用户生成高质量的文稿。以下是五款值得推荐的AI智能写论文软件&#xff0c;其中特别推荐千笔-AIPas…

Path系统环境变量和CLASSPATH环境变量

Path系统环境变量 概述&#xff1a;Path环境变量不是java的&#xff0c;它隶属于windows操作系统 作用&#xff1a; PATH环境变量实际上就是给windows操作系统指路的。 在Path环境变量中有很多路径&#xff0c;路径和路径之间采用 分号(;) 隔开在DOS命令窗口中输入一条DOS命…

Vscode中搭建ABAP开发环境

文章目录 前提&#xff08;在SAP系统中测试&#xff09;1.1 登录sap 系统1.2激活测服务测试1.3 添加服务 下载Vscode2.1 安装ABAP Remote filesystem 打开ABAP System3.1 按照CtrlshiftP 找到AbapFs Connect to an ABAP system 前提&#xff08;在SAP系统中测试&#xff09; 1…

2-89 基于matlab的图像去噪方法

基于matlab的图像去噪方法&#xff0c;对比了常见的几种去噪方法&#xff0c;含中值滤波&#xff0c;均值滤波&#xff0c;维纳滤波&#xff0c;高斯滤波&#xff0c;以及三种形态学滤波&#xff08;一般的&#xff0c;改进的&#xff0c;多结构元素形态学滤波&#xff09;&…

HarmonyOS开发之Tab样式(背景高亮样式)

一&#xff1a;开发环境 二&#xff1a;效果图 三&#xff1a;实现步骤 Entry Component struct TabsPage {State tabArray:string[] ["首页","分类","应用","热点","我的"]State focusIndex: number 0;State index: num…

嵌入式学习(哈希表)

哈希表中元素是由哈希函数确定的&#xff0c;将数据元素的关键字key作为自变量&#xff0c;通过一定的函数关系&#xff08;称为哈希函数&#xff09;&#xff0c;计算出的值&#xff0c;即为该元素的存储地址。 哈希函数&#xff1a;指将哈希表中元素的关键键值映射为元素存储…

局域网远程桌面工具:NoMachine 介绍、安装与使用

局域网远程桌面工具&#xff1a;NoMachine 介绍、安装与使用 NoMachine 简介Linux 安装Windows安装使用 NoMachine 简介 NoMachine是一款很常见的远程桌面工具&#xff0c;尤其在EDA领域&#xff0c;常常被用作远程接入方案。NoMachine可以用于个人远程连接&#xff0c;类似于…

4.第二阶段x86游戏实战2-CE加强修改移动速度(浮点数存放方式与转换)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

2.3.2 协程调度器实现与性能测试

LINUX 精通 8 day24 20240909 晚19&#xff1a;35 - 20: 47 课程链接地址 老师画图用的是excalidraw 可以在线 本地&#xff01; Excalidraw&#xff1a;开源实用的白板画图工具&#xff08;在线/本地安装&#xff09;-CSDN博客 2.3.2 协程调度器实现与性能测试 复习了上…

HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)

跟着该视频学习&#xff0c;记录笔记&#xff1a;【黑马程序员pink老师前端入门教程&#xff0c;零基础必看的h5(html5)css3移动端前端视频教程】https://www.bilibili.com/video/BV14J4114768?p12&vd_source04ee94ad3f2168d7d5252c857a2bf358 Day3 内容梳理&#xff1a;…

使用ChatGPT生成爆款小红书文案,有手就行!

小红书&#xff0c;作为当下热门的社交电商平台&#xff0c;以其独特的社区氛围、精准的用户画像和高粘性的互动模式&#xff0c;吸引了大量年轻用户&#xff0c;尤其是女性用户。平台上的内容风格多样&#xff0c;涵盖了美妆、时尚、生活方式等多个领域。 本文将介绍小红书平台…

为何家用无线路由器不能实现PROFINET通信?

家用无线路由器和工业通信设备到底有什么不同&#xff1f;工控人加入PLC工业自动化精英社群 首先&#xff0c;在技术上&#xff0c;两者存在明显的差异。 家用无线路由器主要是为了提供互联网接入和家庭设备间的连接&#xff0c;而PROFINET则是专为工业自动化设计的通信协议。就…

1分钟教你用AI制作美女热舞视频,收益可观,操作简单(附工具及教程资料)

美女跳舞&#xff0c;听着是不是就觉得会很哇塞&#xff1f; 不管是男的女的、老的少的都喜欢看&#xff0c;而且一般美女跳舞的账号涨粉都很快&#xff0c;势头都贼猛。 今天就给大家分享一个很热门的小副业——AI美女跳舞。 更多实操和AI绘画工具&#xff0c;可以扫描下方&…