1 動態(tài)數(shù)據(jù)綁定
1) 代碼
function Observer(data){
this.data = data;
this.walk(data);
}
Observer.prototype = {
walk: function(data){
for(let key in data){
// for in 會把對象的原型鏈上所有可枚舉屬性列出來,而我們只想要遍歷對象本身的屬性
if(data.hasOwnProperty(key)) {
// 如果沒有遍歷到最底層,繼續(xù)new Observer
if(data[key] instanceof Object){
new Observer(data[key])
}
this.defineReactive(data, key, data[key]);
}
}
},
defineReactive: function(data, key, val){
Object.defineProperty(data, key, {
enumberable: true,
configurable: true,
get: function(){
console.log('你訪問了 ' + key);
return val
},
set: function(newVal){
if(newVal === val){
return
}
val = newVal;
// 同樣 設(shè)置的值為object 需要new Observer將數(shù)據(jù)進(jìn)行劫持
if(newVal instanceof Object){
new Observer(val)
}
console.log('你設(shè)置了 '+ key + ', 新的值' + newVal);
}
})
}
}
let app1 = new Observer({ name: 'youngwind', age: 110});
let app2 = new Observer({ university: 'bupt', major: 'computer'});
app1.data.name;
app1.data.age = 100;
app2.data.university;
app2.data.major = 'science';
2) 知識點
Object.defineProperty
vue.js 是通過它實現(xiàn)雙向綁定的。我們可以通過這個方法,直接在一個對象上定義一個新的屬性,或者是修改已有的屬性。最終這個方法會返回該對象。它接受3個參數(shù),而且都是必填的。
- object 目標(biāo)對象
- propertyname 需要定義的屬性或方法的名字
- descriptor 屬性描述符
descriptor 屬性的狀態(tài)設(shè)置
【value】屬性的值,默認(rèn)為undefined
【writable】 是否可寫,如果設(shè)置成false,則任何對該屬性改寫的操作都無效,
【configurable】如果為false,就不能再設(shè)置它的(value,writable,configurable)
【enumerable】是否能在for ... in 循環(huán)中遍歷出來或在Object.keys中列舉出來。
注意: 在調(diào)用Object.defineProperty()方法時,如果不指定,configurable, enumerable, writable特性的默認(rèn)值都是false。
【get】一旦目標(biāo)對象訪問該屬性,就會調(diào)用這個方法,并返回結(jié)果。默認(rèn)為undefined。
【set】一旦目標(biāo)對象設(shè)置該屬性,就會調(diào)用這個方法。默認(rèn)為undefined