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 相关文章推荐
解决Extjs4中form表单提交后无法进入success函数问题
Nov 26 Javascript
JavaScript严格模式禁用With语句的原因
Oct 20 Javascript
ExpressJS入门实例
Jan 14 Javascript
JavaScript Sort 的一个错误用法示例
Mar 20 Javascript
详解AngularJS的通信机制
Jun 18 Javascript
基于JavaScript实现文字超出部分隐藏
Feb 29 Javascript
jQuery简单实现页面元素置顶时悬浮效果示例
Aug 01 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
Aug 23 Javascript
jQuery 选择符详细介绍及整理
Dec 02 Javascript
详解写好JS条件语句的5条守则
Feb 28 Javascript
layui动态绑定事件的方法
Sep 20 Javascript
vue router 传参获取不到的解决方式
Nov 13 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中取得URL的根域名的代码
2011/03/23 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
2014/04/25 PHP
在SAE上搭建最新wordpress的方法
2014/12/21 PHP
PHP SplObjectStorage使用实例
2015/05/12 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
ecshop适应在PHP7的修改方法解决报错的实现
2016/11/01 PHP
Thinkphp框架中D方法与M方法的区别
2016/12/23 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
tp5.1 框架join方法用法实例分析
2020/05/26 PHP
实例讲解避免javascript冲突的方法
2016/01/03 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
AngularJS基于provider实现全局变量的读取和赋值方法
2017/06/28 Javascript
VueJs组件prop验证简单介绍
2017/09/12 Javascript
Vue.js项目模板搭建图文教程
2017/09/20 Javascript
vue配置请求本地json数据的方法
2018/04/11 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
2018/09/03 jQuery
AngularJs1.x自定义指令独立作用域的函数传入参数方法
2018/10/09 Javascript
JS复杂判断的更优雅写法代码详解
2018/11/07 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
2019/01/05 jQuery
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
Python类的定义、继承及类对象使用方法简明教程
2015/05/08 Python
python机器学习案例教程——K最近邻算法的实现
2017/12/28 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
Python 支付整合开发包的实现
2019/01/23 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
2019/04/29 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
基于Python把网站域名解析成ip地址
2020/05/25 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
2020/11/26 Python
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
快时尚眼镜品牌,全国连锁眼镜店:LOHO眼镜生活
2018/10/08 全球购物
开展党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
2015年小学远程教育工作总结
2015/07/28 职场文书
一年级语文教学随笔
2015/08/14 职场文书
正确使用MySQL INSERT INTO语句
2021/05/26 MySQL