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 相关文章推荐
执行iframe中的javascript方法
Oct 07 Javascript
JS自调用匿名函数具体实现
Feb 11 Javascript
js实现按钮加背景图片常用方法
Nov 01 Javascript
JS绘制生成花瓣效果的方法
Aug 05 Javascript
jQuery绑定事件-多种实现方式总结
May 09 Javascript
JavaScript中的跨浏览器事件操作的基本方法整理
May 20 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
Dec 14 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
Feb 20 Javascript
vue2的todolist入门小项目的详细解析
May 11 Javascript
Angular2使用vscode断点调试ts文件的方法
Dec 13 Javascript
Vue实现简易计算器
Feb 25 Javascript
elementui的el-popover修改样式不生效的解决
Jun 30 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 操作文件的一些FAQ总结
2009/02/12 PHP
php 字符过滤类,用于过滤各类用户输入的数据
2009/05/27 PHP
PHP自定义函数收代码
2010/08/01 PHP
在thinkphp5.0路径中实现去除index.php的方式
2019/10/16 PHP
jQuery插件的写法分享
2013/06/12 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
jquery1.9 下检测浏览器类型和版本的方法
2013/12/26 Javascript
jQuery中:button选择器用法实例
2015/01/04 Javascript
JQuery判断radio(单选框)是否选中和获取选中值方法总结
2015/04/15 Javascript
JavaScript中用于四舍五入的Math.round()方法讲解
2015/06/15 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
2016/01/13 Javascript
JS拖拽组件学习使用
2016/01/19 Javascript
jQuery日历插件datepicker用法详解
2016/03/03 Javascript
微信小程序 前端源码逻辑和工作流详解
2016/10/08 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
2017/01/22 Javascript
获取url中用&隔开的参数实例(分享)
2017/05/28 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
js排序与重组的实例讲解
2017/08/28 Javascript
写一个移动端惯性滑动&回弹Vue导航栏组件 ly-tab
2018/03/06 Javascript
用node撸一个监测复联4开售短信提醒的实现代码
2019/04/10 Javascript
微信小程序获取位置展示地图并标注信息的实例代码
2019/09/01 Javascript
vue自动化路由的实现代码
2019/09/30 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
python中itertools模块zip_longest函数详解
2018/06/12 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
巴西购物网站:Onofre Agora
2020/06/08 全球购物
简历上的自我评价
2014/02/03 职场文书
原料仓管员岗位职责
2014/04/12 职场文书
党支部创先争优活动总结
2014/08/28 职场文书
大学生作弊检讨书
2014/09/11 职场文书
学生自我鉴定格式及范文
2014/09/16 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
关于元旦的广播稿2016
2015/12/17 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
聊聊redis-dump工具安装问题
2022/01/18 Redis
Nginx安装配置详解
2022/06/25 Servers