let obj = {};
let obj1 = {
name: 'xiaoyu',
age: 18,
}
//实现origin对象代理target对象
function proxyData(origin,target){
Object.keys(target).forEach(function(key){
Object.defineProperty(origin,key,{//定义origin对象的key属性
enumerable: false,
configurable: true,
get: function getter(){
return target[key];//origin[key] = target[key];
},
set: function setter(newValue){
target[key] = newValue;
}
})
})
}
vue中的数据代理也是通过这种方式来实现的。
function MVVM(options) {
this.$options = options || {};
var data = this._data = this.$options.data;
var _this = this;//当前实例vm
// 数据代理
// 实现 vm._data.xxx -> vm.xxx
Object.keys(data).forEach(function(key) {
_this._proxyData(key);
});
observe(data, this);
this.$compile = new Compile(options.el || document.body, this);
}
MVVM.prototype = {
_proxyData: function(key) {
var _this = this;
if (typeof key == 'object' && !(key instanceof Array)){//这里只实现了对对象的监听,没有实现数组的
this._proxyData(key);
}
Object.defineProperty(_this, key, {
configurable: false,
enumerable: true,
get: function proxyGetter() {
return _this._data[key];
},
set: function proxySetter(newVal) {
_this._data[key] = newVal;
}
});
},
};
实现Observe
1、双向数据绑定
数据变动 ---> 视图更新
视图更新 ---> 数据变动
要想实现当数据变动时视图更新,首先要做的就是如何知道数据变动了,可以通过Object.defineProperty()函数监听data对象里的数据,当数据变动了就会触发set()方法。所以我们需要实现一个数据监听器Observe,来对数据对象中的所有属性进行监听,当某一属性数据发生变化时,拿到最新的数据通知绑定了该属性的订阅器,订阅器再执行相应的数据更新回调函数,从而实现视图的刷新。
当设置this.name = 'hello vue'时,就会执行set函数,通知订阅器里的订阅者执行相应的回调函数,实现数据变动,对应视图更新。
function observe(data){
if (typeof data != 'object') {
return ;
}
return new Observe(data);
}
function Observe(data){
this.data = data;
this.walk(data);
}
Observe.prototype = {
walk: function(data){
let _this = this;
for (key in data) {
if (data.hasOwnProperty(key)){
let value = data[key];
if (typeof value == 'object'){
observe(value);
}
_this.defineReactive(data,key,data[key]);
}
}
},
defineReactive: function(data,key,value){
Object.defineProperty(data,key,{
enumerable: true,//可枚举
configurable: false,//不能再define
get: function(){
console.log('你访问了' + key);return value;
},
set: function(newValue){
console.log('你设置了' + key);
if (newValue == value) return;
value = newValue;
observe(newValue);//监听新设置的值
}
})
}
}
内容版权声明:除非注明,否则皆为本站原创文章。
