序
Vue.js是一个开源的前端开发库,通过简单的API提供高效的数据绑定和灵活的组件系统。在前端复杂的生态中,Vue.js近年来受到了一定程度的关注,GitHub上已经有5000个了。
本文是作者在开发实践中踩过的坑。总结分享一下,希望能帮助大家学习Vue。我们来看看详细的介绍:
[问题描述]
v-for遍历数组中有一个空值,这会导致页面报告错误,如下所示:
开发框架以Vue为模型绑定的核心,可以根据错误进行简单的判断:
由于removechild操作不会出现在开发人员编写的代码中,所以它应该是在模型被破坏后由Vue引擎移除dom节点引起的。
错误堆栈信息都在框架的代码中,所以这个操作不能被用户代码触发。
开发者某个进程的运行会100%稳定地触发这个错误。这个错误导致js执行终端,整个程序瘫痪,无法工作。开发人员的操作过程可以简化为以下步骤:
1.访问视图a。
2.访问视图b。
3.将历史记录回滚到a(此处出现错误)
上述跳转关系都是视图跳转,即发生在路由系统内的路由跳转。根据路由逻辑,视图的声明周期功能将在第三步中依次执行,包括:
b视图的取消提交逻辑,包括取消提交前和取消提交后。
视图的渲染,包括渲染前和渲染后。
开发人员只在beforeRender阶段重置模型,几乎可以肯定错误报告是由这些模型重置和赋值操作引起的。逐层排除可以用简单的代码找到重复这个问题的方法。
[再现模式]
准备一个简单的空项目并创建一个新的视图测试。下面的代码分别是js/view/test.js和html/view/test.html,在js/view/test.js中视图对模型的操作可以充分体现重现这个问题的过程。SetTimeout模拟ajax操作,这样可以在多次勾选后将数据设置到模型中,观察Vue对dom节点的创建和销毁。
在$nextTick之后,空的test_arr就是让vue销毁这个数据对应的dom节点。相应的代码如下:
上面的代码可以稳定的重新提问,下面是解决方案。
[解决方案]
这个问题在没有找到解决方案的状态下相对容易解决。以下是一些临时解决方案。
选项1
根据错误消息unsughttypeerror :无法读取null的属性“removeChild”,出现此问题是因为removechild是在null对象上执行的。
修改Vue框架代码,并在此处更改代码:
修改为:
选项2
深入分析,为什么el.parentNode为null,通过上面重现的步骤,发现当代码设置的那个。model.test _ arr=['',' 4 ',' ',' 5 ',' 6 ',' ']发生时,v-for生成的dom节点是三个而不是五个。在这种情况下,
方案三
这个问题不是一个令人满意的解决办法。在正常情况下,框架应该是健壮的,并适应不同的使用场景。应该没有js报错的问题,所以有必要进一步研究。
Vue中有一个可选的v-for指令跟踪配置:
无跟踪:当数据被修改时,不管值是否被修改,dom都会被重新呈现。
跟踪情况:当数据被修改时,未更改数据所在的dom不会被重新呈现,而更改数据所在的dom会被重新呈现。
因为v-for默认通过数据对象的特性来决定现有范围和DOM元素的复用程度,这可能会导致整个列表的重新呈现。但是,如果每个对象都有一个唯一的标识属性,您可以使用跟踪功能给Vue一个提示,这样Vue就可以尽可能地重用现有的实例。所以还有第三种解决方案。
[原因分析]
v-for的遍历数组中存在空值,导致页面错误,主要是因为遍历条件中的值判断存在问题。为了保证dom节点的重用,Vue构建了一个由id访问的dom缓存,从数据中分析dom_id,然后根据id从缓存中获取dom节点。因为不同的数据获得相同的dom_id,所以不创建dom节点。但是,当最终数组为空,并且在模型更改后移除dom节点时,将为这些dom节点(即方案1中的兼容代码)触发移除操作:
因此,问题必然出现在函数getTrackByKey的执行中。下面是getTrackByKey的代码:
Vue中数据绑定的操作大大提高了开发者应用开发的效率,但同时也存在一些不易察觉的问题,尤其是当文中问题的重现条件比较复杂时,测试可能覆盖不到问题的触发条件,此时开发者需要更加警惕。
摘要
以上就是本文的全部内容。希望本文的内容能给你的学习或工作带来一些帮助。有问题可以留言交流。谢谢你的支持。