解决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})

最近更新

  1. TCP协议是安全的吗?

    2024-01-07 01:16:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-07 01:16:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-07 01:16:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-07 01:16:03       20 阅读

热门阅读

  1. [数理统计]中国科技技术大学缪柏其

    2024-01-07 01:16:03       30 阅读
  2. 常见的深度相机品牌有哪些。

    2024-01-07 01:16:03       33 阅读
  3. 线特征_LSD直线检测算法和LBD直线描述子

    2024-01-07 01:16:03       37 阅读
  4. k8s之pod进阶

    2024-01-07 01:16:03       31 阅读
  5. Android 车联网——CarManager管理器(四)

    2024-01-07 01:16:03       42 阅读
  6. Android.mk 常用模块类型

    2024-01-07 01:16:03       30 阅读
  7. Go语言程序设计-第6章--方法

    2024-01-07 01:16:03       39 阅读
  8. 后端开发——JDBC的学习(二)

    2024-01-07 01:16:03       36 阅读
  9. Web网页开发-总结笔记1

    2024-01-07 01:16:03       33 阅读