解决vue3中watch 监听不到旧值的问题,亲测有效!

本文主要是介绍解决vue3中watch 监听不到旧值的问题,亲测有效!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述

这个问题是我在公司vue3项目的时候发现的一个问题,watch 在监听对象/数组变量的变化时,发现对象的数据变化时 旧数据 获取到的和新数据是一样的 类似于下面这样

const obj=ref({a:'我是原来的值',b:6,
})obj.a='改变值'watch(obj,(nel,old)=>{
console.log ('打印出来的值',nel,old) 
},{deep:true})

数据变化之后显示出来的如下 :

打印出来的值 {a:'改变值',b:6 } {a:'改变值',b:6 }

当我打印出同样数据的时候 我一脸懵逼 甚至于怀疑自己代码写错了。但是检查一圈 发现代码没有任何错误。然后我用数组去实验了一下 发现 监听数组时也监听到的都是新数据。


原因分析:

发现这个问题之后 我去查看了vue3的官方文档 发现如下图,vue官方说 不能直接不能直接侦听响应式对象的属性值,需要用一个返回该属性的 getter 函数。大家可以点击下方地址查看vue3的官方文档

网址:侦听器 | Vue.js (vuejs.org)

重点解析:     必须看这里 才能了解原理

接着 我研究了一下了解到了不能直接侦听响应式对象的属性值:

因为Vue 3使用了新的响应式系统,它在内部使用了Proxy来实现数据的响应式。

Vue 3的watch选项提供了两个参数:新值和旧值。但是,在旧值参数中,Vue 3只会提供一个代理对象,而不是真正的旧值。这是因为Vue 3的响应式系统将数据封装在Proxy对象中,以便在数据变化时触发更新。

由于代理对象是一个引用类型,它会在数据变化时自动更新。因此,无法直接访问到真正的旧值。如果需要对比旧值和新值,可以手动保存旧值,并与新值进行比较。


解决方案:

了解了上面的原因 ,我想到了 可以用计算属性 就可以继续监听整个对象, 当然大家也可以更具vue文档来一个个属性去监听(我觉得这样太麻烦了),所以最终解决方案 请看下面代码

原理是既然引用类型不能获取旧值 那我们就用computed 定义一个新的变量 这个变量的值是字符串,那么字符串不是引用类型 就可以监听变化 获取旧值。自此解决此问题

const obj=ref({a:'我是原来的值',b:6,
})//我们再用一个计算属性来监听字符串obj对象的变化
const objStr=computed(() => JSON.stringify(obj))obj.a='改变值'//这样就能监听了
watch(objStr,(nel,old)=>{
//记得用的时候转回对象就好
console.log ('打印出来的值',nel,old) 
},{deep:true})

这篇关于解决vue3中watch 监听不到旧值的问题,亲测有效!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

springboot报错Invalid bound statement (not found)的解决

《springboot报错Invalidboundstatement(notfound)的解决》本文主要介绍了springboot报错Invalidboundstatement(not... 目录一. 问题描述二.解决问题三. 添加配置项 四.其他的解决方案4.1 Mapper 接口与 XML 文件不匹配

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作