1 动态数据绑定
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)) {
// 如果没有遍历到最底层,继续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;
// 同样 设置的值为object 需要new Observer将数据进行劫持
if(newVal instanceof Object){
new Observer(val)
}
console.log('你设置了 '+ 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 是通过它实现双向绑定的。我们可以通过这个方法,直接在一个对象上定义一个新的属性,或者是修改已有的属性。最终这个方法会返回该对象。它接受3个参数,而且都是必填的。
- object 目标对象
- propertyname 需要定义的属性或方法的名字
- descriptor 属性描述符
descriptor 属性的状态设置
【value】属性的值,默认为undefined
【writable】 是否可写,如果设置成false,则任何对该属性改写的操作都无效,
【configurable】如果为false,就不能再设置它的(value,writable,configurable)
【enumerable】是否能在for ... in 循环中遍历出来或在Object.keys中列举出来。
注意: 在调用Object.defineProperty()方法时,如果不指定,configurable, enumerable, writable特性的默认值都是false。
【get】一旦目标对象访问该属性,就会调用这个方法,并返回结果。默认为undefined。
【set】一旦目标对象设置该属性,就会调用这个方法。默认为undefined