Vue 传参踩坑之旅——事件总线与 props

news2024/11/18 3:28:20

Vue 传参踩坑之旅——事件总线与 props

缘由

今天突然发现项目出现了一个 bug,这里简单描述一下。

这里有 A、B、C、D 四个组件,关系为 A - 祖先、B - 父、C - 子、D - 叔(实际业务组件关系复杂很多)。

  • A - 祖先
    • B - 父
      • C - 子
    • D - 叔

现在 C 组件要用到 D 组件中的一个方法,由于组件关系比较复杂,我为了省事直接使用 mitt 进行自定义事件的触发,但是 D 组件又可能有多个(通过 v-for 生成的),此时就出现了问题,当存在多个 D 组件时,在 C 组件中调用了 D 中的方法会同时触发所有 D 组件的该事件。

有的小伙伴看完就知道问题所在了,没明白的也没关系,下面我会结合代码进行详细说明。

代码详细说明

先说明一下目录结构:

- App.vue
- A.vue
- B.vue
- C.vue
- D.vue
- mitt.js
<!-- App.vue -->
<template>
  <A v-for="item of 2" :key="item"></A>
</template>

<script setup>
import A from "./A.vue";
</script>
<!-- A.vue -->
<template>
  <B></B>
  <D></D>
</template>

<script setup>
import B from "./B.vue";
import D from "./D.vue";
</script>
<!-- B.vue -->
<template>
  <C></C>
</template>

<script setup>
import C from "./C.vue";
</script>
<!-- C.vue -->
<template>
  <button @click="handleDFunction">点击触发D组件方法</button>
</template>

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

function handleDFunction() {
  mitt.emit("handled");
}
</script>
<!-- D.vue -->
<template></template>

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

function handled() {
  console.log("D组件方法被触发");
}
mitt.on("handled", handled);
</script>
import mitt from 'mitt'

export default new mitt()

以上就是精简后的示例代码,可以简单理解为兄弟组件传参。

效果展示

此时页面会显示两个 <button> 按钮。

在这里插入图片描述

当随便点击了一个后会输出两次 “D组件方法被触发”。

在这里插入图片描述

我们想要的效果是只会触发当前兄弟组件的事件,而此时触发了所有 D 组件的该事件。

问题分析

这个 bug 的原因其实也很简单,这是由于 mitt.on 注册同名事件会在数组后面追加,而非覆盖或者其他思路,简单通过代码说明一下它的源码实现:

function mitt() {
  const eventMap = new Map(); // 事件表
  return {
    // 事件注册
    on(key, callback) {
      // 获取当前名称的事件列表
      const curEventList = eventMap.get(key)
      
      // 不是第一次注册该名称的事件,追加到数组最后
      if (curEventList) {
        curEventList.push(callback)
      }
      // 第一次注册该名称的事件,事件表中添加该事件列表
      else {
        eventMap.set(key, [callback])
      }
    },
    // 事件派发
    emit(key, ...args) {
      // 获取当前名称的事件列表
      const curEventList = eventList.get(key)
      
      // 存在该事件,则遍历数组依次执行
      if (curEventList) {
        curEventList.forEach((curEvent) => {
          curEvent(args)
        })
      }
    },
  }
}

现在就能知道为什么会出现这种问题了,因为每一个 D 组件都对该事件名称进行了注册,因此实际上该事件名称注册了 n 个该事件,所以当 emit 派发时就会依次执行。

解决的化只需要将 emit 替换为 props / emits 就解决了。

总结

这个 bug 其实给了我蛮多启发的,也能理解之前看到别人说业务组件中尽量使用 props / emits 了,事件总线的原理我其实是知道的,但是还是会产生这种 bug,因为随着业务的发展,新功能的产生以及老功能的优化等都可能对原来的数据结构或组件结构进行更改,在我们写业务代码时是比较难精准的预料到未来的变化的,此时就需要我们的代码有足够高的容错性,诸如 provide / inject、事件总线等组件通信方式固然很方便,但是在代码重构或其他一些比较重大改动时项目的数据流又会变得难以预测。

props / emits 的缺点:

  • 代码量会变得更多、冗余

props / emits 的优点:

  • 组件数据流变得清晰
  • 当项目结构发生变化时重构会更简单
  • 不容易产生奇怪的问题

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

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

相关文章

Leetcode刷题详解——括号生成

1. 题目链接&#xff1a;22. 括号生成 2. 题目描述&#xff1a; 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()…

Linux学习第35天:Linux LCD 驱动实验(二):星星之火可以燎原

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 三、LCD驱动程序编写 需要注意的地方&#xff1a; ①、 LCD 所使用的 IO 配置。 ②、 LCD 屏幕节点修改&#xff0c;修改相应的属性值&#xff0c;换成我们所使…

双十一电视盒子哪个牌子最好?老烧分享电视盒子品牌排行榜

在挑选电视盒子时很多人踩雷&#xff0c;我自己买过十来款电视盒子&#xff0c;存在不少问题&#xff0c;双十一这段时间身边买电视盒子的都会问我电视盒子哪个牌子最好&#xff0c;我今天来分享的是业内最专业的电视盒子品牌排行榜&#xff0c;双十一想买电视盒子可以从下面这…

TikTok和创作者经济:成为数字创意产业的一部分

在数字时代&#xff0c;社交媒体已成为了人们日常生活的一部分&#xff0c;不仅改变了我们与世界互动的方式&#xff0c;还催生了全新的产业——创作者经济。 作为这一趋势的一部分&#xff0c;TikTok已经崭露头角&#xff0c;成为数字创意产业的一部分&#xff0c;让创作者有…

ROS服务Service通信机制在无人车中的具体应用

1、引言 我们在通信机制中&#xff0c;前面已有介绍这个Service服务&#xff1a;ROS通信机制之服务(Service)的应用 一般在一些通信处理比较简单的场景比较适合&#xff0c;这里我们在无人车上面来实际操作一些很常见的服务&#xff1a;发布电压数据、点亮与关闭LED灯、开启与…

关于变电站综合自动化系统的案例应用分析-安科瑞 蒋静

摘 要&#xff1a;变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计&#xff0c;利用先进的计算机技术、通信技术、信号处理技术&#xff0c;实现对全变电站的主要设备和输、配电线路的自动监视、测量、控制、保护、并与上级调度通信的综合性自动化功能。 …

【Linux】编译安装nginx,手写service配置文件,深度理解systemd控制管理服务底层原理

目录 一、了解服务 1、服务的本质 2、centos7的systemd的服务 3、service unit file配置文件的组成以及掌握常用选项 4、关于systemd管理的命令学习 5、运行级别 二、编译安装nginx&#xff0c;以及手写service配置文件&#xff0c;请看注释 ​编辑 一、了解服务 1、服…

AI+BI行业数字化转型研讨会 - 总结精华回顾

带您一起观看研讨会精彩内容回顾&#xff01; || 导语 AIBI行业数字化转型研讨会—引领未来&#xff0c;智慧转型 德昂信息技术(北京)有限公司于2023年10月26日成功举办了AIBI行业数字化转型研讨会。此次盛会汇聚了产业精英、企业领袖以及技术专家&#xff0c;共同探讨在快速…

白盒测试用例的设计(图文讲解,超详细)

正文 语句覆盖&#xff1a;每条语句至少执行一次。判定覆盖&#xff1a;每个判定的所有可能结果至少出现一次。&#xff08;又称“分支覆盖”&#xff09;条件覆盖&#xff1a;每个条件的所有可能结果至少执行一次。判定/条件覆盖&#xff1a;一个判定中的每个条件的所有可能结…

多行业万能预约门店小程序源码系统 轻松预约 避免排队 带完整搭建教程

大家好啊&#xff0c;今天源码小编来给大家分享一款超级好用的多行业万能预约门店小程序源码系统。随着人们的生活节奏越来越快&#xff0c;对方便、快捷的服务需求越来越高。在消费升级的大背景下&#xff0c;多行业万能预约门店小程序源码系统的开发应运而生&#xff0c;旨在…

使用内网穿透工具,远程测试本地接口

学习目标&#xff1a; 目标 含义&#xff1a; 内网穿透工具是一种能够帮助没有公网IP或者动态IP用户进行远程访问内网应用的工具。通过内网穿透&#xff0c;用户无论身处任何网络环境&#xff0c;都可以方便地访问企业内部的ERP、OA、CRM等应用。内网穿透工具还支持默认的Htt…

XCC批量更新固件微码

适用&#xff1a; XCC Web界面微码批量更新&#xff0c;通过NFS或CIFS存储库更新所有适用于此服务器的固件微码&#xff0c;实现减少操作步骤&#xff0c;缩短时间周期。 更新事项 更新所有符合XCC更新规则的固件微码&#xff0c;包括UEFI、XCC、LXPM、网卡、RAID卡、RAID H…

【广州华锐互动】影视制作VR在线学习:身临其境,提高学习效率

随着科技的不断发展&#xff0c;影视后期制作技术也在日新月异。然而&#xff0c;传统的教学方式往往难以满足学员的学习需求&#xff0c;无法充分展现影视后期制作的魅力和潜力。近年来&#xff0c;虚拟现实(VR)技术的崛起为教学领域带来了新的机遇。通过VR教学课件&#xff0…

iOS代码混淆----自动

​ 先大致解释一下“编译"、"反编译": 编译&#xff1a;就是把千千万万行字符串(也叫代码&#xff0c;或者源文件)&#xff0c;变成010101010101(机器码&#xff0c;也叫目标代码) 编译过程&#xff1a;预处理-编译-汇编-链接 我的脚本运行在预处理阶段。 反…

技术干货 | GreatDB新一代读写分离架构,如何炼就近乎0损耗的性能?

优化数据库性能并降低成本是每位架构师和DBA都必须面对的挑战。其中&#xff0c;读写分离是一种常见方法&#xff1a;即通过将读操作和写操作分发到不同的数据库实例&#xff0c;实现多副本负载和性能提升。 传统的中间件方案&#xff0c;例如基于Proxysql、HAProxy、MySQL Ro…

社科赛斯预测考研趋势,竞争白热化后,稳上岸还是冲名校?

对于考研党来说&#xff0c;择校应该是备考过程中最纠结的一件事情了。这几年来影响院校选择的情况愈加复杂多变&#xff0c;单一志愿的限制下&#xff0c;如何预测报名走向&#xff0c;如何选择院校才能够成功上岸&#xff0c;不像是一个人的战斗&#xff0c;更像是一场几百万…

机器学习基础之《回归与聚类算法(5)—分类的评估方法》

问题&#xff1a;上一篇的案例&#xff0c;真的患癌症的&#xff0c;能被检查出来的概率&#xff1f; 一、精确率和召回率 1、混淆矩阵 在分类任务下&#xff0c;预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合&#xff0c;构成混淆矩阵(适…

法大大助力“民营旅行社第一股”数字化创新!

根据中国文旅部统计数据显示&#xff0c;2010-2019年&#xff0c;国内旅游市场持续平稳增长&#xff0c;2019年国内旅游人数突破60亿人次&#xff0c;而进入2020年&#xff0c;疫情的暴发使得全球旅游业遭受大创&#xff0c;国内旅游人次也跌至28.79亿人次。如今伴随着政策及环…

美元持续下跌,亚洲新兴市场货币有望脱颖而出?

KlipC报道&#xff1a;在过去几个月&#xff0c;美元大跌成了外汇市场最显眼的主题&#xff0c;追踪美元兑其他十种货币汇率的彭博美元现货指数上周也重挫了近1.5%&#xff0c;创下7月以来最大的周跌幅。 周一&#xff08;11月6日&#xff09;&#xff0c;由于美联储减弱强硬言…

电路设计中的 “热地” 和 “冷地”

一次跳闸事故引起的对 “热地” 的认识 ...... by 矜辰所致前言 最近做了一个简单的小设备&#xff0c;从某宝采购的便宜的成品带外壳&#xff0c;自己改造一下换成带无线通讯的产品&#xff0c;使用过程中忽略了阻容降压只有 “ 热地 ” 的问题&#xff0c;整得跳闸了好几次…