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 相关文章推荐
写出更好的JavaScript之undefined篇(上)
Nov 22 Javascript
jQuery EasyUI中对表格进行编辑的实现代码
Jun 10 Javascript
基于Javascript实现二级联动菜单效果
Mar 04 Javascript
JavaScript 弹出子窗体并返回结果到父窗体的实现代码
May 28 Javascript
微信小程序中的swiper组件详解
Apr 14 Javascript
微信小程序实战之自定义抽屉菜单(7)
Apr 18 Javascript
React.Js添加与删除onScroll事件的方法详解
Nov 03 Javascript
JavaScript canvas实现围绕旋转动画
Nov 18 Javascript
Vue项目实现简单的权限控制管理功能
Jul 17 Javascript
angular组件间通讯的实现方法示例
May 07 Javascript
vue.js实现h5机器人聊天(测试版)
Jul 16 Javascript
JavaScript中条件语句的优化技巧总结
Dec 04 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
杏林同学录(八)
2006/10/09 PHP
php下通过POST还是GET来传值
2008/06/05 PHP
基于php实现长连接的方法与注意事项的问题
2013/05/10 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
PHP+redis实现微博的推模型案例分析
2019/07/10 PHP
加速IE的Javascript document输出的方法
2010/12/02 Javascript
分享27个jQuery 表单插件集合推荐
2011/04/25 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
JS 跳转页面延迟2种方法
2013/03/29 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
Bootstrap每天必学之面板
2015/11/30 Javascript
jQuery ajax分页插件实例代码
2016/01/27 Javascript
AngularJS+Bootstrap实现多文件上传与管理
2016/11/08 Javascript
js实现简单的获取验证码按钮效果
2017/03/03 Javascript
详解vue-cli项目中的proxyTable跨域问题小结
2018/02/09 Javascript
vue3.0 CLI - 3.2 路由的初级使用教程
2018/09/20 Javascript
微信小程序封装的HTTP请求示例【附升级版】
2019/05/11 Javascript
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
Python正则表达式教程之三:贪婪/非贪婪特性
2017/03/02 Python
Python升级导致yum、pip报错的解决方法
2017/09/06 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
2018/10/29 Python
在python中bool函数的取值方法
2018/11/01 Python
python3中类的继承以及self和super的区别详解
2019/06/26 Python
印度最大的时尚购物网站:Myntra
2018/09/13 全球购物
Speedo速比涛法国官方网站:泳衣、泳镜、泳帽、泳裤
2019/07/30 全球购物
CHRONEXT英国:您的首选奢华腕表目的地
2020/03/30 全球购物
暑期社会实践方案
2014/02/05 职场文书
《雪地里的小画家》教学反思
2014/02/22 职场文书
物流管理专业自荐信
2014/06/23 职场文书
网上祭英烈活动总结
2015/02/04 职场文书
大学毕业论文致谢词
2015/05/14 职场文书
小马王观后感
2015/06/11 职场文书
职场领导同事生日简短祝福语
2019/08/06 职场文书
开学季:喜迎新生,迎新标语少不了
2019/11/07 职场文书
Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题
2022/02/12 Redis