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 相关文章推荐
javascript动画之圆形运动,环绕鼠标运动作小球
Jul 20 Javascript
关于IE BUG与字符串截取substr的解决办法
Apr 10 Javascript
JS如何将UTC格式时间转本地格式
Sep 04 Javascript
基于Javascript实现二级联动菜单效果
Mar 04 Javascript
浅谈Cookie的生命周期问题
Aug 02 Javascript
angular实现商品筛选功能
Feb 01 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
深入理解Commonjs规范及Node模块实现
May 17 Javascript
深入理解Node module模块
Mar 26 Javascript
JavaScript设计模式之装饰者模式实例详解
Jan 17 Javascript
vue发送websocket请求和http post请求的实例代码
Jul 11 Javascript
利用JavaScript写一个简单计算器
Nov 27 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
php checkbox复选框值的获取与checkbox默认值输出方法
2010/05/15 PHP
php不写闭合标签的好处
2014/03/04 PHP
CI框架Session.php源码分析
2014/11/03 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
2014/11/14 PHP
PHP输出两个数字中间有多少个回文数的方法
2015/03/23 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
php动态变量定义及使用
2015/06/10 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
extjs grid取到数据而不显示的解决
2008/12/29 Javascript
js 日期转换成中文格式的函数
2009/07/07 Javascript
JavaScript:Div层拖动效果实例代码
2013/08/06 Javascript
JS合并数组的几种方法及优劣比较
2014/09/19 Javascript
jQuery中dequeue()方法用法实例
2014/12/29 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
2015/02/13 Javascript
Svg.js实例教程及使用手册详解(一)
2016/05/16 Javascript
AngularJS指令详解及示例代码
2016/08/16 Javascript
详解JS-- 浮点数运算处理
2016/11/28 Javascript
基于bootstrap风格的弹框插件
2016/12/28 Javascript
js实现导航栏中英文切换效果
2017/01/16 Javascript
ES6新特性之Object的变化分析
2017/03/31 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
2019/08/20 Javascript
ES2020让代码更优美的运算符 (?.) (??)
2021/01/04 Javascript
python Flask实现restful api service
2017/12/04 Python
python机器学习案例教程——K最近邻算法的实现
2017/12/28 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
Python开启线程,在函数中开线程的实例
2019/02/22 Python
Tensorflow加载Vgg预训练模型操作
2020/05/26 Python
Python Sqlalchemy如何实现select for update
2020/10/12 Python
寒假思想汇报
2014/01/10 职场文书
员工培训邀请函
2014/02/02 职场文书
道德之星事迹材料
2014/05/03 职场文书
体育比赛口号
2014/06/09 职场文书
2014年保育员工作总结
2014/12/02 职场文书
2016年国庆节67周年活动总结
2016/04/01 职场文书