- A+
所属分类:javascript JS框架
"use strict";
function MVVM(data){
var data = this.$data = data,
me = this;
this.$watch = function(exp, cb){
return new Watcher(me, exp, cb);
};
Object.keys(data).forEach(function(key){
me._proxy(key);
});
new Observer(data, this);
};
MVVM.prototype = {
_proxy : function(key){
var me = this;
Object.defineProperty(me, key, {
configurable : false,
enumerable : true,
get : function(){
return me.$data[key];
},
set : function(val){
me.$data[key] = val;
}
})
}
};
function Observer(data, self){
this.data = data;
this.mvvm = self;
this.walk(data);
};
Observer.prototype = {
walk : function(data){
var me = this;
Object.keys(data).forEach(function(key){
me.convert(key, data[key]);
});
},
convert : function(key, val){
this.defineReactive(this.data, key, val);
},
defineReactive : function(obj, key, val){
var me = this,
dep = new Dep(),
childObj = observer(val);
Object.defineProperty(obj, key, {
enumerable : true,
configurable : false,
get : function(){
if(Dep.target) dep.depend(dep);
return val;
},
set : function(newVal){
if(val === newVal) return;
childObj = observer(newVal);
val = newVal;
dep.notify();
}
})
}
};
function observer(val){
if(!val || typeof val !== 'object') return;
return new Observer(val);
};
const Dep = (function(){
var UUID = 0;
return function(){
this.UUID = UUID++;
this.subs = [];
}
})();
Dep.target = null;
Dep.prototype = {
depend : function(dep){
Dep.target.addDeps(dep);
},
addSub : function(sub){
this.subs.push(sub);
},
notify : function(){
this.subs.forEach(function(sub){
sub.updata();
});
}
};
function Watcher(vm, exp, cb){
this.cb = cb;
this.vm = vm;
this.exp = exp;
this.depIds = {};
this.value = this.get();
};
Watcher.prototype = {
addDeps : function(dep){
if( !this.depIds.hasOwnProperty(dep.uuid) ){
dep.addSub(this);
this.depIds[dep.uuid] = dep;
}
},
get : function(){
Dep.target = this;
var value = this.vm[this.exp];
Dep.target = null;
return value;
},
updata : function(){
this.run();
},
run : function(){
var newVal = this.get(),
oldVal = this.value;
if(newVal !== oldVal){
this.cb.call(this, newVal, oldVal);
oldVal = newVal;
}
}
};
var o = {name:'LXY', age:'24'};
var vm = new MVVM(o);
vm.$watch('name', function(newVal, oldVal){
console.log([newVal, oldVal]);
});
vm.$watch('age', function(newVal, oldVal){
console.log([newVal, oldVal]);
});
vm.name = 'ASD';
vm.age = '10';

我的微信
欢迎来撩!!