问题记录排查问题的方法总结vue3中数据失去响应式?为什么数据变了,视图只更新了一次就不再更新了?

Posted 黑子Kuroko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问题记录排查问题的方法总结vue3中数据失去响应式?为什么数据变了,视图只更新了一次就不再更新了?相关的知识,希望对你有一定的参考价值。

一、问题概述:

持续请求的数据变动之后,控制台输出绑定的响应式变量 mapObj 的确变了,但是视图上只更新了一次,后续就不再更新了。

二、排查过程:

PC上用定时器setInterval模拟数据(全是小于0的数据)更新,视图的确响应了。 -- bug无法复现

手机上控制台输出关键信息,输出内容一切都符合预期,但是视图层面上只有部分组件数据更新了,有几个组件的数据只更新了一次,后续再也不更新。--bug偶现。

前期很快定位到:

数据响应式失效了,视图层失去了响应。

尝试解决方案:

reactive 改用 ref 来包装对象 -- 未解决

对象直接赋值,改为对象内部属性赋值 -- 未解决

vm.$forceUpdate() 迫使Vue实例重新渲染 -- 未解决

。。。

成功解决:

排查好几天之后,尝试将当前处理过的数据未处理的原始数据同时绑定在组件上,比对成功!处理过的数据视图不更新,但是未处理的原始数据终于响应式更新了。--bug已定位。

再通过比对当前处理过的数据和未处理的原始数据区别,即可发现数据更新之后所执行的函数内部有一个逻辑会执行 el.innerText = el.innerText.trim() 数据转换,并且仅当数据大于0的时候进入到这行代码注释该行代码,数据恢复响应,问题解决。--bug成功解决。

三、反思总结

解决问题并不难,难的是排查问题。

其实最终的解决方案一点也不🐮👃,就是注释一行错误代码,可以说一点营养🥛也没有。

但是这个问题解决的过程却是特别漫长,其中的干扰因素太多、尝试过的解决手段也很多、瞎JB乱想的因素更多(例如什么vue框架本身的响应延迟等等,更是走了很多弯路)。

所以既然花了那么多时间去解决了这个问题,这个问题必定可以榨出一些营养出来的。

这次排查耗时这么久总结出来最关键的2个点,后续一定要牢记:

1、比对问题要全面!

该问题当中有出现正常和异常的两种表现,但是当时只注意到对象key值的不同,却没注意到对象value值的不同。

这就好像我们小时候玩的两幅画找不同的游戏一样,只找出了其中一处不同点(还是错误的方向),没发现还有很多其他不同的点!

当时如果注意到大于0异常,小于0正常,这一特性的话,定位问题就简单多了。

不过当时数据也少,的确很难察觉到会是伴随着数据value不同而出现,这个倒也无可厚非。

2、模拟问题要干净!

模拟问题的时候不够彻底的干净,这是最最最最最最最最最最最最致命的错误!

当很快定位到是数据响应式问题的时候,应该直接模拟将原数据绑定在组件dom上,而不是包了一层handler函数的数据。

// 演示代码

import  handlerFn  from ../XXX

const mapObj = ref();

const changeInterval = setInterval(()=>
  mapObj.value[key] = newValue;
, 3000);

// 错误的模拟方式
<div> handlerFn(mapObj[key]) </div>


// 正确的模拟方式
<div> mapObj[key] </div>

// 进阶模拟方式 - 比对定位
<div> handlerFn(mapObj[key])  - 我是分割符 -  mapObj[key] </div>

下班下班,周五愉快 ~  🎉 🎉 🎉 

 

以上是关于问题记录排查问题的方法总结vue3中数据失去响应式?为什么数据变了,视图只更新了一次就不再更新了?的主要内容,如果未能解决你的问题,请参考以下文章

vue3(语法糖)reactive数据直接赋值将失去响应式

Vue3 解构赋值失去响应式引发的思考!

Vue3 解构赋值失去响应式引发的思考!

Vue3 reactive丢失响应式问题

有啥方法可以让 Vue3 中的 sessionStorage 响应式?

vue2响应式原理总结