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 相关文章推荐
不能再简单的无闪刷新验证码原理很简单
Nov 05 Javascript
JS 的应用开发初探(mootools)
Dec 19 Javascript
将文本输入框内容加入表中的js代码
Aug 18 Javascript
JS中实现replaceAll的方法(实例代码)
Nov 12 Javascript
jQuery找出网页上最高元素的方法
Mar 20 Javascript
原生JS实现图片左右轮播
Dec 30 Javascript
JavaScript表单验证的两种实现方法
Feb 11 Javascript
JavaScript对象原型链原理解析
Jan 22 Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 Javascript
js判断密码强度的方法
Mar 18 Javascript
JavaScript ECMA-262-3 深入解析(二):变量对象实例详解
Apr 25 Javascript
解决vant title-active-color与title-inactive-color不生效问题
Nov 03 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 无限分类的树类代码
2009/12/03 PHP
教你如何使用php session
2013/10/28 PHP
php 获取页面中指定内容的实现类
2014/01/23 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP进阶学习之类的自动加载机制原理分析
2019/06/18 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
2010/01/15 Javascript
JS实现控制表格单元格垂直对齐的方法
2015/03/30 Javascript
JavaScript弹出新窗口并控制窗口移动到指定位置的方法
2015/04/06 Javascript
JavaScript中Number.MIN_VALUE属性的使用示例
2015/06/04 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
基于jQuery实现简单的折叠菜单效果
2015/11/23 Javascript
详述JavaScript实现继承的几种方式(推荐)
2016/03/22 Javascript
浅谈JavaScript的全局变量与局部变量
2016/06/10 Javascript
jQuery实现公告新闻自动滚屏效果实例代码
2016/07/14 Javascript
jquery层级选择器的实现(匹配后代元素div)
2016/09/05 Javascript
JavaScript获取select中text值的方法
2017/02/13 Javascript
Bootstrap的popover(弹出框)2秒后定时消失的实现代码
2017/02/27 Javascript
Easyui和zTree两种方式分别实现树形下拉框
2017/08/04 Javascript
Vue2实时监听表单变化的示例讲解
2018/08/30 Javascript
element ui table 增加筛选的方法示例
2018/11/02 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
ES2020让代码更优美的运算符 (?.) (??)
2021/01/04 Javascript
[02:31]2014DOTA2国际邀请赛2009专访:干爹表现出乎意料 看好DK杀回决赛
2014/07/20 DOTA
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[01:08:33]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python 专题一 函数的基础知识
2017/03/16 Python
如何用Python来搭建一个简单的推荐系统
2019/08/07 Python
浅析Python语言自带的数据结构有哪些
2019/08/27 Python
css3的focus-within选择器的使用
2020/05/11 HTML / CSS
H5 video poster属性设置视频封面的方法
2020/05/25 HTML / CSS
领先的荷兰线上超市:荷兰之家Holland at Home(支持中文)
2021/01/21 全球购物
2015年世界卫生日活动总结
2015/02/09 职场文书
母亲节寄语大全
2015/02/27 职场文书
MATLAB 如何求取离散点的曲率最大值
2021/04/16 Python