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

相关文章

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom

使用mvn deploy命令上传jar包的实现

《使用mvndeploy命令上传jar包的实现》本文介绍了使用mvndeploy:deploy-file命令将本地仓库中的JAR包重新发布到Maven私服,文中通过示例代码介绍的非常详细,对大家的学... 目录一、背景二、环境三、配置nexus上传账号四、执行deploy命令上传包1. 首先需要把本地仓中要

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

Java springBoot初步使用websocket的代码示例

《JavaspringBoot初步使用websocket的代码示例》:本文主要介绍JavaspringBoot初步使用websocket的相关资料,WebSocket是一种实现实时双向通信的协... 目录一、什么是websocket二、依赖坐标地址1.springBoot父级依赖2.springBoot依赖

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

Java使用Mail构建邮件功能的完整指南

《Java使用Mail构建邮件功能的完整指南》JavaMailAPI是一个功能强大的工具,它可以帮助开发者轻松实现邮件的发送与接收功能,本文将介绍如何使用JavaMail发送和接收邮件,希望对大家有所... 目录1、简述2、主要特点3、发送样例3.1 发送纯文本邮件3.2 发送 html 邮件3.3 发送带

Nginx如何进行流量按比例转发

《Nginx如何进行流量按比例转发》Nginx可以借助split_clients指令或通过weight参数以及Lua脚本实现流量按比例转发,下面小编就为大家介绍一下两种方式具体的操作步骤吧... 目录方式一:借助split_clients指令1. 配置split_clients2. 配置后端服务器组3. 配

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

使用DeepSeek搭建个人知识库(在笔记本电脑上)

《使用DeepSeek搭建个人知识库(在笔记本电脑上)》本文介绍了如何在笔记本电脑上使用DeepSeek和开源工具搭建个人知识库,通过安装DeepSeek和RAGFlow,并使用CherryStudi... 目录部署环境软件清单安装DeepSeek安装Cherry Studio安装RAGFlow设置知识库总

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP