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 相关文章推荐
Jquery 跨域访问 Lightswitch OData Service的方法
Sep 11 Javascript
jquery实现弹出div,始终显示在屏幕正中间的简单实例
Mar 08 Javascript
两种不同的方法实现js对checkbox进行全选和反选
May 13 Javascript
Bootstrap框架动态生成Web页面文章内目录的方法
May 12 Javascript
使用bootstrap-paginator.js 分页来进行ajax 异步分页请求示例
Mar 09 Javascript
详解JS中遍历语法的比较
Apr 07 Javascript
Angular 向组件传递模板的两种方法
Feb 23 Javascript
vue数组对象排序的实现代码
Jun 20 Javascript
vue生成token并保存到本地存储中
Jul 17 Javascript
JavaScript实现的九种排序算法
Mar 04 Javascript
js实现掷骰子小游戏
Oct 24 Javascript
解决antd的Form组件setFieldsValue的警告问题
Oct 29 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
给海燕B411配件机起死回生配上件
2021/03/02 无线电
ajax缓存问题解决途径
2006/12/06 PHP
比较简单实用的PHP无限分类源码分享(思路不错)
2011/10/13 PHP
JQuery优缺点分析说明
2010/06/09 Javascript
JS中window.open全屏命令解析及使用示例
2013/12/11 Javascript
JavaScript从数组中删除指定值元素的方法
2015/03/18 Javascript
jQuery动态添加
2016/04/07 Javascript
深入浅出ES6之let和const命令
2016/08/25 Javascript
BootStrap table使用方法分析
2016/11/08 Javascript
canvas实现图片根据滑块放大缩小效果
2017/02/24 Javascript
Node.js中看JavaScript的引用
2017/04/22 Javascript
Vue单页式应用(Hash模式下)实现微信分享的实例
2017/07/21 Javascript
JS正则表达式完美实现身份证校验功能
2017/10/18 Javascript
基于javascript中的typeof和类型判断(详解)
2017/10/27 Javascript
使用Vue写一个datepicker的示例
2018/01/27 Javascript
Vue 页面权限控制和登陆验证功能的实例代码
2019/06/20 Javascript
python生成指定尺寸缩略图的示例
2014/05/07 Python
跟老齐学Python之编写类之一创建实例
2014/10/11 Python
快速查询Python文档方法分享
2017/12/27 Python
浅谈python中拼接路径os.path.join斜杠的问题
2018/10/23 Python
Python通用函数实现数组计算的方法
2019/06/13 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
Python partial函数原理及用法解析
2019/12/11 Python
python已协程方式处理任务实现过程
2019/12/27 Python
Python基础类继承重写实现原理解析
2020/04/03 Python
Python while true实现爬虫定时任务
2020/06/08 Python
聊聊python中的异常嵌套
2020/09/01 Python
TIME时代杂志台湾总代理:台时亚洲
2018/10/22 全球购物
Gloeilampgoedkoop荷兰:在线购买灯泡
2019/02/16 全球购物
村创先争优活动总结
2014/08/28 职场文书
党的群众路线教育实践活动个人对照检查材料(公安)
2014/11/05 职场文书
客房领班岗位职责
2015/02/11 职场文书
外贸英文求职信范文
2015/03/19 职场文书
JVM之方法返回地址详解
2022/02/28 Java/Android
电脑关机速度很慢怎么办 提升电脑关机速度设置教程
2022/04/08 数码科技
MySQL实现字段分割一行转多行的示例代码
2022/07/07 MySQL