当前位置: 首页 > news >正文

eventbus,在this.$on监听事件时无法在获取数据

问题:vue中eventbus被多次触发,在this.$on监听事件时,内部的this发生改变导致,无法在vue实例中添加数据。

项目场景

一开始的需求是这样的,为了实现两个组件(A.vue ,B.vue)之间的数据传递。 页面A,点击页面上的某个A上的某一个按钮之后,页面会跳转到页面B。这个时候需要将页面A上的数据携带过去给页面B。

// 发送数据的组件
<template><div><button @click="increment">emit</button></div>
</template><script>
export default {name: 'Achild',methods: {increment() {this.bus.$emit('increment', '我是increment')}},
</script>
<template><div>I am BChild<p>{{info}}</p></div>
</template>
// 接受数据的组件
<script>
export default {name: 'Bchild',data() {return {info: 'default info'}},// 放在crerated()生命周期,且使用箭头函数才能将数据挂载到接受数据组件的this上created() {let _this = thisconsole.log('Bchild this', this)this.bus.$on('increment', data => {this.info = data})},
</script>

按照理论,我觉得只要在页面A触发了increment事件,页面B就会理所当然的接受了数据。然而,结果却不如人意。

img

从这里可以发现 页面B根本就没有接收到这个事件

img

然后再从页面B回退到 页面A, 再重复一遍emit increment事件。会神奇的发现B竟然收到了 A传递过来的数据。

preview

你会发现,第一次触发事件increment的时候,B并没有收到。 第二次触发的时候,就输出了一个。第三次触发的时候,就又输出了两个依次增加。而且你还会发现打印出的on的回调函数打印出的this指向,并不是指向当前vue实例(B.vue)。而且明明是顺序执行,却偏偏是异步执行。on的回调函数先于 console.log(‘Bchild this’, this)执行。

  • 问题1:为什么第一次触发事件的时候,页面B on没有监听到事件。
  • 问题2:为什么后面再一次依次去触发的时候会出现,每一次都会发现好像之前的on事件分发都没有被撤销一样,导致每一次的事件触发执行越来越多。
  • 问题3:为什么是on里的回调函数先执行? 输出的指向且并不指向当前vue实例?

解决

这些问题的出现还要从vue的生命周期讲起。大家可以自己去学习Vue生命周期的钩子。

v4

从这里我们可以清楚的看到,当我们还在页面A触发emit事件时,页面B还没有生成,也就是说页面B中created中所监听的来自于A中的事件还没有被触发。这个时候你A中emit事件的时候,B还没有监听到。

再仔细看看,当我们从A页面跳转到B页面中的时候发生了什么?首先是B组件created 然后beforeMounted接着A组件才被销毁,A组件才仔细beforeDestory,以及destoryed。然后B组件再执行mounted。 所以我们可以把A页面组件中的emit事件放到beforeDestory里,因为这个时候,B组件的created钩子已经执行,也就可以监听到从A传过来的事件了。而且从周期来看,B的$on监听,也不能放在mounted钩子里,不然也会出现监听不到的情况。

<template><div>I am AChild<button @click="increment">emit</button></div>
</template><script>
export default {name: 'Achild',methods: {increment() {console.log('A触发了 $emit')this.$router.push('/B')}},beforeDestroy () {this.bus.$emit('increment', '我是increment')}}
</script>

修改过后效果图:

v5

我们可以看到修改后,B明显可以收到A传递过来的数据。但是多次点击,事件的触发还是会依次增加,控制台打印的输出每次都有增加。而且每次在$on里的回调函数会打印出以前监听到的vue实例,和本次监听的实例。

总结

查找各方面资料,才知道**$on事件是不会自动销毁的。需要我们手动来销毁。**

这是因为Bus是全局的,并不随着页面的切换而重新执行生命周期,所以$on能存储到以前的实例,这样看起来才比较奇怪。如果没有A组件没有将emit放在beforeDestory钩子里,通过全局的事件总线bus(没有受生命周期约束),而B里的 o n 里没有监听到最新的 e m i t ,只会收到以前的事件,所以 on里没有监听到最新的emit,只会收到以前的事件,所以 on里没有监听到最新的emit,只会收到以前的事件,所以on的this会指向上次B.vue的vue实例。导致现在的B.vue就算看起来拿到了数据,也无法挂载到现在的B实例上。

所以在B组件添加

beforeDestroy () {this.bus.$off('increment')
}

建议

使用bus时一定要注意,组件的生命周期。对于这种会被销毁的vue实例。一定要把emit放在beforeDestory里面。并且要记得将$on销毁。

如果是要保存这种状态最好使用vuex,进行数据传递。这样这些传递的值,就不会受组件的销毁新建的影响,可以保存下来。

相关文章:

eventbus,在this.$on监听事件时无法在获取数据

问题&#xff1a;vue中eventbus被多次触发&#xff0c;在this.$on监听事件时&#xff0c;内部的this发生改变导致&#xff0c;无法在vue实例中添加数据。 项目场景 一开始的需求是这样的&#xff0c;为了实现两个组件(A.vue ,B.vue)之间的数据传递。 页面A&#xff0c;点击页面…...

【Python必做100题】之第二十五题(统计字符)

题目&#xff1a;输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其他字符的个数 代码如下&#xff1a; string input("请输入字符串:")char 0 number 0 space 0 other 0for i in string:if i.isalpha():char 1elif i.isdigit():number 1eli…...

开发语言:ArkTS

简介 ArkTS是华为为鸿蒙操作系统&#xff08;HarmonyOS&#xff09;开发的一种应用开发语言。这种语言在TypeScript&#xff08;简称TS&#xff09;的基础上进行了扩展&#xff0c;以更好地适应鸿蒙系统的特点和开发需求。ArkTS不仅继承了TS的所有特性&#xff0c;而且还对TS的…...

Qt中字符串转换为JS的函数执行

简介 在 QML 中&#xff0c;将 JavaScript 字符串转换为函数通常涉及使用 Function 构造函数或 eval() 函数。但是&#xff0c;QML 的环境对 JavaScript 的支持有一定的限制&#xff0c;因此不是所有的 JavaScript 功能都可以在 QML 中直接使用。 以下介绍都是在Qt5.12.1…...

TCP/IP:从数据包到网络的演变

引言 TCP/IP协议的起源可以追溯到20世纪60年代末和70年代初&#xff0c;美国国防部高级研究计划局&#xff08;ARPA&#xff09;研究开发一种可靠的通信协议&#xff0c;用于连接分散在不同地点的计算机和资源。 在当时&#xff0c;计算机之间的连接并不像现在这样普遍和便捷…...

闪存驱动器与机械硬盘与固态硬盘

目录 U盘&#xff08;闪存驱动器&#xff09; 固态硬盘&#xff08;SSD&#xff09; 机械硬盘&#xff08;HDD&#xff09; 目前主流 U盘&#xff08;闪存驱动器&#xff09; U盘是便携式存储设备&#xff0c;内部采用闪存芯片作为存储介质。它们通常具有小巧轻便的外形&am…...

java String转asc码,然后ascII再转四位的16进制数。

理论知识补充&#xff1a; char是Java中的保留字&#xff0c;表示一种数据类型。与别的语言不同的是&#xff0c;char在Java中是16位的&#xff0c;因为Java用的是Unicode编码。不过8位的ASCII码包含在Unicode编码中&#xff0c;其值对应十进制的表示范围是0~127。 char是Java八…...

零基础制作宠物用品小程序

随着人们对宠物用品的需求不断增长&#xff0c;越来越多的人开始探索如何制作一个专业的宠物用品小程序。而乔拓云作为一款功能强大的在线商城制作工具&#xff0c;成为了许多商家的首选。本文将详细介绍如何使用乔拓云制作宠物用品小程序&#xff0c;让你轻松上手&#xff0c;…...

【SpringBoot篇】解决缓存击穿问题① — 基于互斥锁方式

文章目录 &#x1f339;什么是缓存击穿&#x1f33a;基于互斥锁解决问题&#x1f6f8;思路 &#x1f3f3;️‍&#x1f308;代码实现 &#x1f339;什么是缓存击穿 缓存击穿是指在使用缓存系统时&#xff0c;对一个热点数据的高并发请求导致缓存失效&#xff0c;多个请求同时访…...

系列一、GitHub搜索技巧

一、GitHub搜索技巧 1.1、概述 作为程序员&#xff0c;GitHub大家应该都再熟悉不过了&#xff0c;很多时候当我们需要使用某一项技能而又无从下手时&#xff0c;通常会在百度&#xff08;面向百度编程&#xff09;或者在GitHub上通过关键字寻找相关案例&#xff0c;比如我想学…...

35.java后端面试宝典

一、自我介绍。 我叫什么&#xff0c;这次是应聘什么岗位&#xff0c;会什么技术&#xff0c;会什么框架&#xff0c;熟练掌握框架之间的整合技术&#xff0c;做过什么项目并且介绍主要做了什么&#xff0c;并且可以为公司带来什么价值。 总的来说&#xff0c;初级Java工程师岗…...

Linux 磁盘空间占满故障解决方法

故障排查&#xff1a; 使用命令查看磁盘使用量 # 使用人类可读的格式(预设值是不加这个选项的...) df -h # --inodes 列出 inode 资讯&#xff0c;不列出已使用 block df -i # 查看当前目录下各个文件及目录占用空间大小 du -sh / 情况一&#xff1a;一般磁盘空间满了&a…...

让生活更智能,P1600边缘智能网关带你进入智能家居新时代

一、什么是P1600边缘智能网关&#xff1f; 在科技日新月异的今天&#xff0c;我们的生活已经被各种智能产品所包围。而在这个智能化的浪潮中&#xff0c;P1600边缘智能网关以其独特的优势&#xff0c;成为了智能家居的重要组成部分。那么&#xff0c;什么是P1600边缘智能网关呢…...

Java与前端:2023年的真实状况与焦虑解读

一、引言 在2023年&#xff0c;IT圈中流传着一些关于Java和前端的言论&#xff0c;这些言论引起了广泛的关注。有些人认为“Java已死、前端已凉”&#xff0c;而另一些人则持不同观点。那么&#xff0c;这些言论背后的真相是什么&#xff1f;它们是在贩卖焦虑吗&#xff1f;本…...

adb 基本命令合集

1.获取所有的包信息&#xff1a; adb shell pm list packages com.yu.weskul 2.清除APP缓存 adb shell pm clear <package-name> 3.查看当前应用及Activity adb shell dumpsys window | findstr "mCurrentFocus" 4.查看应用详细信息 adb shell dumpsys pack…...

[RK-Linux] RK3399支持M.2 NVMe SSD启动

延续《[RK-Linux] 从主线U-Boot移植PCIe及其PHY驱动到RK3399 U-Boot》 启动流程: maskrom -> loader(从 eMMC 存储器加载) -> u-boot(从 eMMC 存储器加载)-> kernel (从 M.2 NVMe SSD 加载)-> rootfs (从 M.2 NVMe SSD 挂载)配置从 M.2 NVMe SSD 启动: …...

LTO-3 磁带机种草终于是用上了

跑来跑去&#xff0c;买了不少配件&#xff0c;终于是把这磁带机给用上了&#xff0c;已经备份好了300 多 GB 的数据。 我们用了 NAS 的数据压缩功能&#xff0c;把需要备份的文件用 NAS 压缩成一个 Zip 文件&#xff0c;如果你可以 tar 的话也行。 这样传输速度更快&#xf…...

【全网首发】洛谷P1020 [NOIP1999 提高组] 导弹拦截

P1020 导弹拦截 の 题目传送门。 解题思路 显然&#xff0c;第一问求的是最长不上升子序列。 于是接下来直接抛开第一问不谈&#xff0c;也不考虑优化&#xff0c;直接考虑第二问。待会就知道原因了。 引理&#xff1a;Dilworth 定理 狄尔沃斯定理亦称偏序集分解定理&#…...

trino-435版本windows下源码编译

一、源码下载地址 https://github.com/trinodb/trino/tags 二、编译环境及工具准备 1、maven &#xff08;1&#xff09;版本&#xff1a;3.6.3 &#xff08;2&#xff09;settings.xml配置 <?xml version"1.0" encoding"UTF-8"?> <settin…...

java类和对象的思想概述

0.面向对象Object OOP——名人名言&#xff1a;类是写出来的&#xff0c;对象是new出来的 **> 学习面向对象的三条路线 java类以及类成员&#xff1a;&#xff08;重点&#xff09;类成员——属性、方法、构造器、&#xff08;熟悉&#xff09;代码块、内部类面向对象特征&…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...