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 相关文章推荐
HTTP状态代码以及定义(解释)
Feb 02 Javascript
判断JavaScript对象是否可用的最正确方法分析
Oct 03 Javascript
一个基于jquery的文本框记数器
Sep 19 Javascript
JS鼠标滑过图片时切换图片实现思路
Sep 12 Javascript
JavaScript中的条件判断语句使用详解
Jun 03 Javascript
原生JavaScript实现Ajax的方法
Apr 07 Javascript
Bootstrap项目实战之首页内容介绍(全)
Apr 25 Javascript
轻松学习Javascript闭包
Mar 01 Javascript
详解如何用webpack打包一个网站应用项目
Jul 12 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
Aug 25 Javascript
vue.js与element-ui实现菜单树形结构的解决方法
Apr 21 Javascript
layui上传图片到服务器的非项目目录下的方法
Sep 26 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实现Ftp用户的在线管理的代码
2007/03/06 PHP
令PHP初学者头疼十四条问题大总结
2008/11/12 PHP
php完全过滤HTML,JS,CSS等标签
2009/01/16 PHP
解决phpmyadmin中缺少mysqli扩展问题的方法
2013/05/06 PHP
PHP指定截取字符串中的中英文或数字字符的实例分享
2016/03/18 PHP
100多行PHP代码实现socks5代理服务器[2]
2016/05/05 PHP
PHP array_shift()用法实例分析
2019/01/07 PHP
Laravel框架文件上传功能实现方法示例
2019/04/16 PHP
extjs fckeditor集成代码
2009/05/10 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
JavaScript中的稀疏数组与密集数组[译]
2012/09/17 Javascript
图片上传插件jquery.uploadify详解
2013/11/15 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
jQuery 选择同时包含两个class的元素的实现方法
2016/06/01 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
详解微信小程序开发之城市选择器 城市切换
2017/01/17 Javascript
angular和BootStrap3实现购物车功能
2017/01/25 Javascript
微信小程序 实现动态显示和隐藏某个控件
2017/04/27 Javascript
JavaScript简单实现合并两个Json对象的方法示例
2017/10/16 Javascript
React Native AsyncStorage本地存储工具类
2017/10/24 Javascript
JS+CSS3实现的简易钟表效果示例
2019/04/13 Javascript
json字符串对象转换代码实例
2019/09/28 Javascript
vue全局使用axios的操作
2020/09/08 Javascript
python操作xml文件示例
2014/04/07 Python
python检测远程udp端口是否打开的方法
2015/03/14 Python
Python爬虫设置代理IP的方法(爬虫技巧)
2018/03/04 Python
win7 x64系统中安装Scrapy的方法
2018/11/18 Python
python实现二分查找算法
2020/09/18 Python
经济实惠的豪华背包和行李袋:Packs Project
2018/10/17 全球购物
求最大连续递增数字串(如"ads3sl456789DF3456ld345AA"中的"456789")
2015/09/11 面试题
历史学专业毕业生求职信
2013/09/27 职场文书
四查四看剖析材料
2014/02/14 职场文书
高中课程设置方案
2014/05/28 职场文书
夫妻分居协议书范本
2014/11/28 职场文书
mysql 带多个条件的查询方式
2021/06/05 MySQL
python脚本框架webpy模板赋值实现
2021/11/20 Python