在 Vue 2 中,当你把一个普通的 JavaScript 对象传入 Vue 实例作为
data
选项,Vue 将遍历此对象所有的 property,并使用Object.defineProperty
把这些 property 全部转为 getter/setter。Object.defineProperty
是 ES5 中一个无法 shim 的特性,这天然的导致无法监听到数组与对象内部的变化,同时也是 Vue 不支持 IE8 以及更低版本浏的原因。
对于对象
Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。
Vue.set(vm.someObject, 'b', 2)
this.$set(this.someObject,'b',2)
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
对于数组
Vue 不能检测以下数组的变动:
- 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue;
- 当你修改数组的长度时,例如:vm.items.length = newLength;
解决方法:
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength)
同时重写了 Array 的多个方法:( 能改变原有数组的API基本都重写了 )
- push
- pop
- shift
- unshift
- splice
- sort
- reverse
方便用户实现数组的响应式
网友评论