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 相关文章推荐
响应鼠标变换表格背景或者颜色的代码
Mar 30 Javascript
HTML5附件拖拽上传drop & google.gears实现代码
Apr 28 Javascript
jquery中animate的stop()方法作用实例分析
Jan 30 Javascript
Js控制滑轮左右滑动实例
Feb 13 Javascript
jQuery对象初始化的传参方式
Feb 26 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
Mar 04 Javascript
JS针对Array的各种操作汇总
Nov 29 Javascript
JS键盘版计算器的制作方法
Dec 03 Javascript
JavaScript设计模式之缓存代理模式原理与简单用法示例
Aug 07 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
Mar 04 Javascript
Vue响应式原理Observer、Dep、Watcher理解
Jun 06 Javascript
解决antd Form 表单校验方法无响应的问题
Oct 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常用文件操作函数和简单实例分析
2016/06/03 PHP
thinkphp的dump函数无输出实例代码
2016/11/15 PHP
jquery tab标签页的制作
2010/05/10 Javascript
js创建对象的几种常用方式小结(推荐)
2010/10/24 Javascript
用jQuery模拟select下拉框的简单示例代码
2014/01/26 Javascript
javascript动态修改Li节点值的方法
2015/01/20 Javascript
Node.js 去掉种子(torrent)文件里的邪恶信息
2015/03/27 Javascript
原生JS实现美图瀑布流布局赏析
2015/09/07 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
详解从Vue.js源码看异步更新DOM策略及nextTick
2017/10/11 Javascript
Vue常用指令详解分析
2018/08/19 Javascript
RequireJS用法简单示例
2018/08/20 Javascript
关于JavaScript中高阶函数的魅力详解
2018/09/07 Javascript
layer父页获取弹出层输入框里面的值方法
2019/09/02 Javascript
vue中英文切换实例代码
2020/01/21 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
[09:22]2014DOTA2西雅图国际邀请赛 主赛事第二日TOPPLAY
2014/07/21 DOTA
python多线程http下载实现示例
2013/12/30 Python
python写的一个文本编辑器
2014/01/23 Python
python实现批量获取指定文件夹下的所有文件的厂商信息
2014/09/28 Python
详解Python中列表和元祖的使用方法
2015/04/25 Python
使用Python实现博客上进行自动翻页
2017/08/23 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
Python爬虫爬取Bilibili弹幕过程解析
2019/10/10 Python
法国珠宝店:CLEOR
2017/01/29 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
纽约和芝加哥当天送花:Ode à la Rose
2019/07/05 全球购物
EJB的基本架构
2016/09/22 面试题
国际商务专业学生个人的自我评价
2013/09/28 职场文书
餐饮商业计划书范文
2014/04/29 职场文书
施工安全承诺书
2014/05/22 职场文书
2015年初中元旦晚会活动总结
2014/11/28 职场文书
一年级语文上册复习计划
2015/01/17 职场文书
初中班主任心得体会
2016/01/07 职场文书