Vue 将遍历其所有属性并使用 Object.defineProperty 将它们转换为 getter/setter
上面这句话的意思是 vue 迭代你的每个属性data
使他们做出反应的选项。
例如,考虑您的data
选项为:
data:{
foo: 'hello world',
bar: 3
}
vue 将覆盖data
对象如下(只是抽象描述):
let key = Object.keys(data)
for (let i = 0; i < keys.length; i++) {
let val = data[keys[i]];
Object.defineProperty(data, keys[i], {
get(){
// add this property as a dependency when accessed
return val;
},
set(newVal){
//notify for a change
val = newVal;
}
})
}
如果你查看 vue源代码 https://github.com/vuejs/vue/blob/dev/src/core/observer/index.js#L143同样,您会发现它检查属性是否具有预定义的 getter 或 setter https://github.com/vuejs/vue/blob/dev/src/core/observer/index.js#L148.
然后它重写属性 getter,如下所示:
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
const value = getter ? getter.call(obj) : val;
if (Dep.target) {
dep.depend();
if (childOb) {
childOb.dep.depend();
if (Array.isArray(value)) {
dependArray(value);
}
}
}
return value;
},
set(newVal) {
//...
}
});
如果你看到这个line https://github.com/vuejs/vue/blob/dev/src/core/observer/index.js#L160 const value = getter ? getter.call(obj) : val;
你会注意到,如果你定义了一个 getter,它就会被使用并且它的值会被返回。
Vue 只是做了更多的工作,通过调用一些依赖相关的方法来使它们具有反应性,就是这样。