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实现页面打印功能实例代码(附去页眉页脚功能代码)
Dec 15 Javascript
jQuery阻止同类型事件小结
Apr 19 Javascript
如何使Chrome控制台支持多行js模式——意外发现
Jun 13 Javascript
用js闭包的方法实现多点标注冒泡示例
May 29 Javascript
用jquery模仿的a的title属性的例子
Oct 22 Javascript
微信开发 微信授权详解
Oct 21 Javascript
关于Vue.js一些问题和思考学习笔记(1)
Dec 02 Javascript
基于Vue的移动端图片裁剪组件功能
Nov 28 Javascript
webpack-dev-server远程访问配置方法
Feb 22 Javascript
vue项目前端错误收集之sentry教程详解
May 27 Javascript
微信小程序如何实现radio单选框单击打勾和取消
Jan 21 Javascript
为react组件库添加typescript类型提示的方法
Jun 15 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实现在线生成条形码示例分享(条形码生成器)
2013/12/30 PHP
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
php生成图片缩略图的方法
2015/04/07 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
2015/04/26 PHP
PHP验证终端类型是否为手机的简单实例
2017/02/07 PHP
PHP框架Laravel中实现supervisor执行异步进程的方法
2017/06/07 PHP
laravel 判断查询数据库返回值的例子
2019/10/11 PHP
如何让您的中波更粗更长 - 中波框形天线制作
2021/03/10 无线电
js 图片等比例缩放代码
2010/05/13 Javascript
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
2014/05/12 Javascript
JS判断当前页面是否在微信浏览器打开的方法
2015/12/08 Javascript
Jquery使用小技巧汇总
2015/12/29 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
2016/05/05 Javascript
深入浅析JS Function()构造函数
2016/08/22 Javascript
es6 字符串String的扩展(实例讲解)
2017/08/03 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
2018/07/16 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
微信小程序实现锚点功能
2019/11/20 Javascript
jQuery实现评论模块
2020/08/19 jQuery
Python不规范的日期字符串处理类
2014/06/10 Python
python实现上传下载文件功能
2020/11/19 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
2017/11/21 Python
Python安装pycurl失败的解决方法
2018/10/15 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
2020/04/08 Python
sklearn中的交叉验证的实现(Cross-Validation)
2021/02/22 Python
Woolworth官网:澳洲第一大超市
2017/06/25 全球购物
店面销售职位的职责
2014/03/09 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
教师专业自荐信
2014/05/31 职场文书
小学班级特色活动方案
2014/08/31 职场文书
售后客服个人自我评价
2014/09/14 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android
nginx lua 操作 mysql
2022/05/15 Servers