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