Vue 中使用事件总线来进行组件间通信($emit()、$on() 和 $off())

本文主要是介绍Vue 中使用事件总线来进行组件间通信($emit()、$on() 和 $off()),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用场景:
上一篇文章中写到的:
echarts图表左击显示自定义弹框,右击取消自定义弹框

结构图:(removet修改为remove)
在这里插入图片描述在这里插入图片描述

假设这个echarts图表是子组件B页面中。而父页面A的自定义弹框标签里调用了子组件B,(v-if判断)当弹框为true时显示子组件B,反之不显示子组件B(没有dom元素);在子组件B中,需要得知父页面A的弹框是否被关闭,才能将子组件里createElement的弹框元素清除。

所以,通过子组件props获取值且在watch监听父页面A的弹框的状态是行不通的,因为在 Vue 中使用 v-if 来判断是否显示某个元素时,当条件为 false 时,对应的 DOM 元素会被移除,这意味着在页面渲染时,如果 v-if 的条件为 false,相关的 DOM 结构将不会存在于最终的渲染结果中,因此子组件B只能监听到父页面A弹框为显示(true)。

但我们需要的是父页面A弹框为隐藏(false)状态时,移除子组件B中的弹框B。

目录

  • vue组件通信方法
    • $emit
    • $on
    • $off
    • 其它vue方法(本文没使用到的)
  • 逻辑分析
    • 全局挂载
    • 父页面
    • 子组件
      • 监听事件
      • 解绑监听事件

vue组件通信方法

官网api文档:点击跳转至vue组件事件的中文官网

$emit

$emit(eventName, ...args):用于在当前实例上触发事件。它接收一个事件名称 eventName 作为第一个参数,可以传递额外的参数作为事件回调函数的参数。当调用 $emit() 方法时,会触发相应的事件,并将参数传递给监听该事件的处理函数。

$on

$on(eventName, callback):用于监听当前实例上的事件。当对应的事件被触发时,注册的回调函数 callback 将会被调用。可以通过 $on() 方法来绑定事件监听器。

$off

$off(eventName, callback):用于移除事件监听器。可以通过 $off() 方法来解绑先前使用 $on() 绑定的事件监听器。如果提供了 eventName 参数,则只会移除该事件相关的监听器;如果同时提供了 eventName 和 callback 参数,则只会移除指定事件及回调函数的监听器。

其它vue方法(本文没使用到的)

$watch():用于侦听 Vue 实例上的数据变化并做出相应的响应。
$nextTick():用于在 DOM 更新之后执行延迟回调函数。
$refs:用于访问子组件或子元素的引用。
this. $ router 和 this. $ route:用于访问 Vue Router 的路由实例和路由信息对象。

示例:

created() {this.$watch("searchdata.isasc", this.handleIsAscChange);
}

逻辑分析

子组件 B 能够在弹框状态为 false 时也能监听到父页面 A 的弹框关闭状态,这就需要使用事件总线来实现,在 Vue 应用中创建一个事件总线 bus,并在父页面 A 中发送事件,子组件 B 监听这个事件来获取父页面弹框状态的变化。

全局挂载

在 main.js 中创建事件总线 bus:

import Vue from 'vue';
export const bus = new Vue();

父页面

父页面 A 中发送事件:

<template><div class="bigbox-class"><el-button type="primary" @click="openClick">显示弹框</el-button><!-- 弹框部分 --><div class="alert-modal-container alertbox" v-if="showModal"><div class="alert-modal-shadow"></div><div class="alert-modal-content"><div class="alert-modal-header"><span>{{ title }}</span><button @click="closeClick">×</button></div><div class="alert-modal-body"><line-standard-com></line-standard-com></div></div></div></div>
</template><script>
import LineStandardCom from "./line-Components/lineCom.vue"; //子组件
import { bus } from './main.js';export default {components: { LineStandardCom },data() {return {showModal: false,title: "弹框名称",};},methods: {closeClick() {this.showModal = false;bus.$emit("modalStateChanged", false);},openClick() {this.showModal = true;bus.$emit("modalStateChanged", true);},}
};
</script>

子组件

监听事件

在子组件 B 中监听事件:

<template><div><!-- 子组件的内容,即上篇文章写到的echarts图表创建弹框元素内容 --></div>
</template><script>
import "./lineStyle.css";//样式页面
import { bus } from './main.js';export default {created() {bus.$on('modalStateChanged', (showModal) => {console.log("showModal", showModal);if (!showModal) { //父组件A的弹框隐藏(false)时console.log('Modal in parent component is closed');}});},
};
</script>

解绑监听事件

上面$on()方法监听方法中输出可以得出,每一次变化弹框状态时,输出showModal次数会递增,意味着会出现内存泄漏或不必要的性能消耗。
在这里插入图片描述

所以在每次组件销毁或离开时,建议及时解绑事件监听。可以在子组件的 beforeDestroy 生命周期钩子中,使用 bus. $off 来解绑事件监听,以确保不会产生不必要的内存消耗。

<script>
import { bus } from './main.js';export default {created() {bus.$on('modalStateChanged', this.handleModalStateChange);},beforeDestroy() {bus.$off('modalStateChanged', this.handleModalStateChange);},methods: {handleModalStateChange(showModal) {if (!showModal) { //父组件A的弹框隐藏(false)时if (this.currentMenu && this.currentMenu.parentNode === document.body) {document.body.removeChild(this.currentMenu); // 清除子组件B弹框的菜单元素}}},}
};
</script>

这篇关于Vue 中使用事件总线来进行组件间通信($emit()、$on() 和 $off())的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829164

相关文章

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

Jsoncpp的安装与使用方式

《Jsoncpp的安装与使用方式》JsonCpp是一个用于解析和生成JSON数据的C++库,它支持解析JSON文件或字符串到C++对象,以及将C++对象序列化回JSON格式,安装JsonCpp可以通过... 目录安装jsoncppJsoncpp的使用Value类构造函数检测保存的数据类型提取数据对json数

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

springboot整合 xxl-job及使用步骤

《springboot整合xxl-job及使用步骤》XXL-JOB是一个分布式任务调度平台,用于解决分布式系统中的任务调度和管理问题,文章详细介绍了XXL-JOB的架构,包括调度中心、执行器和Web... 目录一、xxl-job是什么二、使用步骤1. 下载并运行管理端代码2. 访问管理页面,确认是否启动成功

使用Nginx来共享文件的详细教程

《使用Nginx来共享文件的详细教程》有时我们想共享电脑上的某些文件,一个比较方便的做法是,开一个HTTP服务,指向文件所在的目录,这次我们用nginx来实现这个需求,本文将通过代码示例一步步教你使用... 在本教程中,我们将向您展示如何使用开源 Web 服务器 Nginx 设置文件共享服务器步骤 0 —

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画