一:如何追踪变化?
(1)Object.defineProperty() :Object.defineProperty()把 Vue中data对象所包含的所有属性全部转化为getters/setter。这些getters/setter对用户来说是不可见的,但在内部它们让Vue能够追踪依赖,在属性被访问和修改时通知变更。
(2)watcher:每个组件实例都对应一个watcher实例,它会在组件渲染的过程中把‘接触’过的数据属性记录为依赖。之后当依赖的setter触发时,会通知watcher,从而使它关联的组件重新渲染。
(3)Object.defineProperty() 是ES5无法shim的特性,这也就是为什么VUE不支持IE8及更低版本浏览器的原因。
二:检测变化的注意事项
(1)Object.observe() : 受现代JavaScript的限制(而且Object.observe也已经废除),Vue无法检测到对象属性的增加或删除。由于Vue会在初始化实例时对属性执行getters/setter转化,所以属性必须在data对象上存在才能让Vue将它转化为响应式的。
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的
(2)Vue.Set(object,propertyName,value) :对于已经创建的实例,Vue不允许动态添加根级别的响应式属性。但是,可以使用Vue.set()方法向嵌套对象添加响应式属性。
Vue.set(vm.someObject,'b',2);
//还可以使用全局vm.$set()方法。
(3)Object.assign(),_.extend() : 有时候你可能需要向已有的对象添加多个新属性,可以使用Object.assign()或者_.extend(),但是这样添加到对象上的新属性不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的属性一起创建一个新的对象。
this.someObject = Object.assign( {} , this.someObject , {a:1,b:2} );
三:声明响应式属性
(1)由于Vue不允许动态添加根级别的响应式属性,所以你必须在初始化实例前声明所有根级别响应式属性,哪怕只是一个空值。
var vm = new Vue({
data: {
// 声明 message 为一个空值字符串
message: ''
},
template: '<div>{{ message }}</div>'
})
// 之后设置 `message`
vm.message = 'Hello!'
//如果你未在data选项中声明message,Vue将警告你渲染函数正在试图访问不存在的属性。