核心方法:Object.defineProperty
设计模式:数据劫持,监听者模式
上源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<button onclick="a()">get</button>
<button onclick="b()">set</button>
</body>
</html>
<script type="text/javascript">
//全局watcher容器
var wathcTarget = null;
//对象递归绑定
function forObjBind(o){
for( k in o){
if( typeof o[k] == 'object' ){
forObjBind(o[k])
}else{
objBind(k,o)
}
}
}
function objBind(k,o){
var dsp = new Dsp();
if(watchTarget){
dsp.addSub(watchTarget);
watchTarget = null;
}
var v = o[k];
Object.defineProperty(o,k,{
enumerable: true,
get:function(){
//console.log("get "+k+":", v)
return v;
},
set:function(val){
//console.log("set "+k+":", val)
if(v !== val){
v = val;
dsp.notify(k);
}
v = val;
}
})
}
//消息订阅器
var Dsp = function(){
this.addSub = function(item){
this.subs.push(item);
}
this.notify = function(k){
console.log(this.subs)
this.subs.forEach(function(item){
item.update(k);
})
}
}
Dsp.prototype.subs = [];
//监听者
function watcher(render){
watchTarget = this;
console.log("newWathche")
this.update = function(k){
render(k)
}
}
//VUe
function Vue(ops){
this._data = ops.data();
this.mount = function(){
new watcher(this.render)
forObjBind(this._data)
}
this.render = function(k){
console.log("来自监听的回调" + k + '变了')
}
}
var v = new Vue({
data(){
return {
name:"gaoliang",
age:35
}
}
})
v.mount();
//获取
function a(){
console.log(v._data.name)
}
//设置
function b(){
v._data.age = "haha"
}
</script>