Vue不能观察到数组length的变化


Posted in Javascript onJune 08, 2018

由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength

因为vue的响应式是通过 Object.defineProperty 来实现的,但是数组的length属性是不能添加getter和setter,所有无法通过观察length来判断。

为什么Vue不能观察到数组length的变化

如下代码,虽然看起来数组的length是10,但是for in的时候只能遍历出0, 1, 2,导致了只有前三个索引被加上了getter 和setter

var a = [0, 1, 2]
a.length = 10
// 只是显示的给length赋值,索引3-9的对应的value也会赋值undefined
// 但是索引3-9的key都是没有值的
// 我们可以用for-in打印,只会打印0,1,2
for (var key in a) {
 console.log(key) // 0,1,2
}

那么vue提供了一些解决方法

使用内置的Vue.$set

让数组显式的进行某个索引的观察 Vue.set(array, indexOfItem, newValue)

实际上是调用了

Object.defineProperty(array, indexOfItem, {
 enumerable: true,
 configurable: true,
 get() { },
 set(newVal) { }
})

这样可以手动指定需要观察的key,那么就可以达到预期的效果。

重写了 push, pop, shift, unshift, splice, sort, reverse方法

Vue源码

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

/**
 * Intercept mutating methods and emit events
 */
;[
 'push',
 'pop',
 'shift',
 'unshift',
 'splice',
 'sort',
 'reverse'
]
.forEach(function (method) {
 // cache original method
 const original = arrayProto[method]
 def(arrayMethods, method, function mutator (...args) {
  const result = original.apply(this, args)
  const ob = this.__ob__
  let inserted
  switch (method) {
   case 'push':
   case 'unshift':
    inserted = args
    break
   case 'splice':
    inserted = args.slice(2)
    break
  }
  if (inserted) ob.observeArray(inserted)
  // notify change
  ob.dep.notify()
  return result
 })
})

这些是在Array.__proto__上 进行了方法重写或者添加

并且对添加属性的方法如 push,unshift,splice 所添加进来的新属性进行手动观察,源码为

if (inserted) ob.observeArray(inserted)

对以上方法进行了手动的进行消息触发

ob.dep.notify()

结论

vue对数组的length直接改变无法直接进行观察,提供了vue.$set 进行显式观察,并且重写了 push, pop, shift, unshift, splice, sort, reverse方法来进行隐式观察。

以上所述是小编给大家介绍的Vue不能观察到数组length的变化,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
一个加载js文件的小脚本
Jun 28 Javascript
js数组的操作指南
Dec 28 Javascript
JSON字符串转JSON对象
Jul 31 Javascript
DOM 事件的深入浅出(一)
Dec 05 Javascript
jQuery插件HighCharts绘制2D带Label的折线图效果示例【附demo源码下载】
Mar 08 Javascript
bootstrap table表格使用方法详解
Apr 26 Javascript
JS实现加载时锁定HTML页面元素的方法
Jun 24 Javascript
ExtJs整合Echarts的示例代码
Feb 27 Javascript
React+Webpack快速上手指南(小结)
Aug 15 Javascript
JS使用Prim算法和Kruskal算法实现最小生成树
Jan 17 Javascript
JavaScript代码异常监控实现过程详解
Feb 17 Javascript
javaScript实现一个队列的方法
Jul 14 Javascript
Node.js中的child_process模块详解
Jun 08 #Javascript
详解使用 Node.js 开发简单的脚手架工具
Jun 08 #Javascript
使用JavaScript生成罗马字符的实例代码
Jun 08 #Javascript
jQuery实现表单动态加减、ajax表单提交功能
Jun 08 #jQuery
Node.js中你不可不精的Stream(流)
Jun 08 #Javascript
用react-redux实现react组件之间数据共享的方法
Jun 08 #Javascript
vue指令只能输入正数并且只能输入一个小数点的方法
Jun 08 #Javascript
You might like
echo, print, printf 和 sprintf 区别
2006/12/06 PHP
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
PHP设计模式入门之状态模式原理与实现方法分析
2020/04/26 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
js网页版计算器的简单实现
2013/07/02 Javascript
jQuery实现渐变下拉菜单的简单方法
2015/03/11 Javascript
使用javascript提交form表单方法汇总
2015/06/25 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
JavaScript设计模式之单例模式详解
2017/06/09 Javascript
js数组实现权重概率分配
2017/09/12 Javascript
使用store来优化React组件的方法
2017/10/23 Javascript
5 种JavaScript编码规范
2018/01/30 Javascript
如何在JavaScript中谨慎使用代码注释
2019/06/21 Javascript
JavaScript计算正方形面积
2019/11/26 Javascript
uni-app如何页面传参数的几种方法总结
2020/04/28 Javascript
JS删除对象中某一属性案例详解
2020/09/08 Javascript
vue keep-alive实现多组件嵌套中个别组件存活不销毁的操作
2020/10/30 Javascript
[03:37]2015国际邀请赛第四日现场精彩集锦
2015/08/08 DOTA
pymongo实现控制mongodb中数字字段做加法的方法
2015/03/26 Python
Python中使用dom模块生成XML文件示例
2015/04/05 Python
python通过smpt发送邮件的方法
2015/04/30 Python
对python中大文件的导入与导出方法详解
2018/12/28 Python
python3.6下Numpy库下载与安装图文教程
2019/04/02 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
Python爬虫之urllib基础用法教程
2019/10/12 Python
详解使用Python写一个向数据库填充数据的小工具(推荐)
2020/09/11 Python
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
Everything But Water官网:美国泳装品牌
2019/03/17 全球购物
网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?
2016/03/27 面试题
迎八一活动主题
2014/01/31 职场文书
老人祝寿主持词
2014/03/28 职场文书
暑期教师培训方案
2014/06/07 职场文书
沈阳故宫导游词
2015/01/31 职场文书
JPA如何使用entityManager执行SQL并指定返回类型
2021/06/15 Java/Android
深入理解Pytorch微调torchvision模型
2021/11/11 Python