如何追踪变化
- 把一个普通的 JS 对象传入 Vue 实例 作为
data
选项, Vue 将遍历此对象所有的 property,并使用Object.defineProperty
把这些 property 全部转为 getter/setter,Object.defineProperty
是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染
检测数组与对象的变化
Vue 不能检测数组和对象的变化
- 对于已经创建的实例,Vue 不允许添加跟级别的响应式 property, 只有在初始化实例时处于
data
中的对象才是响应式的 ```javascript var vm = new Vue({ data:{ a:1 } })
// vm.a
是响应式的
vm.b = 2 // vm.b
是非响应式的
解决:
```javascript
Vue.set(vm.someObject, 'b', 2)
Vue 不能检测数组的变动: 使用索引设置数组的元素,修改数组的长度
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
解决:
设置数组元素 ```javascript // Vue.set Vue.set(vm.items, indexOfItem, newValue) vm.$set(vm.items, indexOfItem, newValue) // 实例方法
// Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
- 设置数组长度
```javascript
vm.items.splice(newLength)
声明响应式 property
由于 Vue 不允许动态添加根级响应式 property,所以必须在初始化实例前声明所有根级响应式 property
var vm = new Vue({
data: {
message: ''
},
template: '<div>{{ message }}</div>'
})
vm.message = 'Hello!'
异步跟新 DOM
Vue 在更新 DOM 时事异步的,为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)
。这样回调函数将在 DOM 更新完成后被调用