≡
  • 网络编程
  • 数据库
  • CMS技巧
  • 软件编程
  • PHP笔记
  • JavaScript
  • MySQL
位置:首页 > 网络编程 > vue.js

Vue.js中轻松解决v-for执行出错的三个方案

人气:573 时间:2019-04-07

这篇文章主要为大家详细介绍了Vue.js中轻松解决v-for执行出错的三个方案,具有一定的参考价值,可以用来参考一下。

感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!

 

前言

 

Vue.js 是开源的一个前端开发库,通过简洁的 API 提供高效的数据绑定和灵活的组件系统。在前端纷繁复杂的生态中,Vue.js在近年来受到一定程度的关注,目前在 GitHub上已经有5000+。

本文是笔者在开发实践中踩过的坑,总结和分享出来,希望对大家学习Vue有所帮助。下面来看看详细的介绍:

 

【问题描述】

 

 

v-for遍历数组中存在空值导致页面报错,情况如下:

【图片暂缺】

开发框架是以Vue为模型绑定的核心,根据错误可以进行一个简单的判断:

      ▪ removeChild操作既然不是发生在开发者显示书写的代码中,就应该是模型销毁后Vue引擎移除dom节点导致的。

      ▪ 错误栈信息都在框架的代码之内,此操作不可能是有用户代码触发导致的。

开发者某一流程的操作,会100%稳定地触发出这一错误,此错误导致js执行终端,整个程序陷入瘫痪无法工作,开发者的操作流程可以简化为如下的步骤:

      1. 访问视图A。

      2. 访问视图B。

      3. 回退历史记录到A。(错误发生在这里)

以上的跳转关系都是视图跳转,也就是发生在路由系统之内的路由跳转,按照路由逻辑,第三步的时候会依次执行视图的声明周期函数,包括:

      ▪ B视图的unRender逻辑,包括beforeUnRender和afterUnRender。

      ▪ A视图的Render,包括beforeRender和afterRender。

开发者只在beforeRender的阶段进行了模型重置的操作,几乎可以确定无疑,报错就是由这几行模型重置和赋值的操作引起的。层层排除可以寻找到使用简单代码重新此问题的方式。

 

【重现方式】

 

 

准备一个简单的空工程,新建视图test,一下的代码分别为js/view/test.js和html/view/test.html,js/view/test.js中视图对模型的操作可以完整反映重现此问题的流程。其中,setTimeout模拟的是ajax操作以让数据在多个tick之后设置到模型以观察Vue对dom节点的创建和销毁。

$nextTick之后,将test_arr置空的操作是为了使vue将此数据对应的dom节点销毁,对应代码如下:

【图片暂缺】

以上的代码可以稳定重新问题,下面是解题思路。

 

【解决方案】

 

在不求甚解的状态下,这个问题是比较容易解决的,这里有几个临时的解决方案。

 

▲方案一

 

 

从报错信息Uncaught TypeError: Cannot read property 'removeChild' of null可知,之所以发生这个问题是因为在null的对象上执行了removeChild。

修改Vue框架代码,将这里的代码:

【图片暂缺】

修改为:

【图片暂缺】

 

▲方案二

 

 

深入地分析,为什么el.parentNode会是null,通过上面重现的步骤发现,当that.model.test_arr = ["","4","","5","6",""]这段代码设置发生后,v-for产生的dom节点之后3个,而不是5个,这种情况下el.parentNode就是不存在的,所以产生了第二种解决方案,强制不给空数据的元素生成dom节点。

【图片暂缺】

 

▲方案三

 

 

问题并不算是圆满解决,正常的情况下框架应该具有鲁棒性,适应不同的使用场景,不应该出现js报错的问题,所以还有深入研究下去的必要。

在Vue中针对v-for指令有一个track-by的可选配置:

       ▪无track-by情况:数据修改时,无论值是否被修改,dom都被重新渲染。

       ▪有track-by情况:数据修改时,不变数据所在的dom不被重新渲染,已改变的数据所在dom才被重新渲染。

因为 v-for 默认通过数据对象的特征来决定对已有作用域和 DOM 元素的复用程度,这可能导致重新渲染整个列表。但是,如果每个对象都有一个唯一 ID 的属性,便可以使用 track-by 特性给 Vue 一个提示,Vue因而能尽可能地复用已有实例。所以就有了第三种解决方案。


【图片暂缺】

 

【原因分析】

 

 

v-for遍历数组中存在空值导致页面报错,主要是遍历条件里对值的判断有问题。Vue为了保证对dom节点的复用,内置了一份按照id存取的dom缓存,通过对数据分析出dom_id,然后根据此id从缓存中获取dom节点。由于不同的数据取到了相同的dom_id,所以没有创建dom节点出来。但是,在最终数组置空,模型变更之后dom节点移除的时候却为这些dom节点触发了remove操作,也就是方案一中兼容的那些代码:

【图片暂缺】

所以问题必定出现在getTrackByKey这个函数的执行上,以下是getTrackByKey的代码:

【图片暂缺】

Vue中对数据绑定的操作大大地提高了开发者应用开发的效率,但与此同时也伴随着一些不易察觉的问题,尤其如本文中问题的重现条件比较复杂的情况下,测试不一定可以覆盖到问题的触发条件,这个时候就需要开发人员多一分警惕。

 

总结

 

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对四海网的支持。

本文来自:http://www.q1010.com/184/3436-0.html

注:关于Vue.js中轻松解决v-for执行出错的三个方案的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。

关键词:vue.js

您可能感兴趣的文章

  • vue.js中过滤器的使用教程
  • 基于vue2.0实现的级联选择器
  • 浅谈 Vue v-model指令的实现原理
  • vue2 中如何实现动态表单增删改查实例
  • vue2.0 自定义日期时间过滤器
  • vue.js+Echarts开发图表放大缩小功能实例
  • 手把手搭建安装基于windows的Vue.js运行环境
  • vue中如何实现变量和字符串拼接
  • 分析Vue组件之间的数据通信实例
  • 分析Vue整合axios的实例代码
上一篇:Vue非父子组件通信分析
下一篇:手把手搭建安装基于windows的Vue.js运行环境
热门文章
  • Vue 报错TypeError: this.$set is not a function 的解决方法
  • vue实现动态添加数据滚动条自动滚动到底部的示例代码
  • vue项目设置scrollTop不起作用(总结)
  • vue项目中使用vue-i18n报错的解决方法
  • iview实现select tree树形下拉框的示例代码
  • 分析关于element级联选择器数据回显问题
  • vue项目打包后打开页面空白解决办法
  • 解决element ui select下拉框不回显数据问题的解决
  • element-ui table span-method(行合并)的实现代码
  • element-ui 设置菜单栏展开的方法
  • 最新文章
    • 理解vue ssr原理并自己搭建简单的ssr框架
    • vue favicon设置以及动态修改favicon的方法
    • vue-router启用history模式下的开发及非根目录部署方法
    • 从零开始在NPM上发布一个Vue组件的方法步骤
    • Element input树型下拉框的实现代码
    • Vue 报错TypeError: this.$set is not a function 的解决方法
    • Vue.js组件高级特性实例分析
    • 浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
    • 分析Vue.js自定义tipOnce指令用法实例
    • 浅谈vuex actions和mutation的异曲同工

四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。