參考版本 vue源碼版本:0.11
相關(guān)
vue實現(xiàn)雙向數(shù)據(jù)綁定的關(guān)鍵是 Object.defineProperty ,讓我們先來看下這個函數(shù)。
在MDN上查看有關(guān) Object.defineProperty 的解釋鼻忠。
我們先從最簡單的開始:
let a = {'b': 1};
Object.defineProperty(a, 'b', {
enumerable: false,
configurable: false,
get: function(){
console.log('b' + '被訪問');
},
set: function(newVal){
console.log('b' + '被修改生百,新' + 'b' + '=' + newVal);
}
});
a.b = 2; // b被修改,新b=2
a.b; // b被訪問
這樣,我們就能監(jiān)聽對象了拉队!但問題并不僅僅這么簡單。阻逮。粱快。
我們可能會有對象中屬性的值還是對象這種嵌套情況,可以通過遞歸解決叔扼!
在vue源代碼文件 src\observe\observer.js 中
// 觀察者構(gòu)造函數(shù)
function Observer(data){
this.data = data;
this.walk(data);
}
let p = Observer.prototype;
p.walk = function(obj){
let val;
for(let key in obj){
// 通過 hasOwnProperty 過濾掉一個對象本身擁有的屬性
if(obj.hasOwnProperty(key)){
val = obj[key];
// 遞歸調(diào)用 循環(huán)所有對象出來
if(typeof val === 'object'){
new Observer(val);
}
this.convert(key, val);
}
}
};
p.convert = function(key, val){
Object.defineProperty(this.data, key, {
enumerable: false,
configurable: false,
get: function(){
console.log(key + '被訪問');
},
set: function(newVal){
console.log(key + '被修改事哭,新' + key + '=' + newVal);
if(newVal === val) return ;
val = newVal;
}
})
};
let data = {
user: {
name: 'zhangsan',
age: 14
},
address: {
city: 'beijing'
}
}
let app = new Observer(data);
data.user.name; // user被訪問