//为每个节点建立订阅者,通过订阅者watcher初始化及更新视图数据
new watcher(vm,node,name);
//-----------------------
}
}
}
//----------------------------------------------------------------
//订阅者(为每个节点的数据建立watcher队列,每次接受更改数据需求后,利用劫持数据执行对应节点的数据更新)
function watcher(vm,node,name){
//将每个挂载了数据的dom节点添加到通知者列表,要保证每次创建watcher时只有一个添加目标,否则后续会因为watcher是全局而被覆盖,所以每次要清空目标
Dep.target = this;
this.vm = vm;
this.node = node;
this.name = name;
//执行update的时候会调用监听者劫持的getter事件,从而添加到watcher队列,因为update中有访问this.vm[this.name] this.update();
//为保证只有一个全局watcher,添加到队列后,清空全局watcher
Dep.target = null;
}
watcher.prototype = {
update(){
this.get();
//input标签特殊处理化
if(this.node.nodeName === 'INPUT'){
this.node.value = this.value;
}
else{
this.node.nodeValue = this.value;
}
},
get(){
//这里调用了数据劫持的getter
this.value = this.vm[this.name];
}
};
//通知者(将监听者的更改信息需求发送给订阅者,告诉订阅者哪些数据需要更改)
function Dep(){
this.subs = [];
}
Dep.prototype = {
addSub(watcher){
//添加用到数据的节点进入watcher队列
this.subs.push(watcher);
},
notify(){
//遍历watcher队列,令相应数据节点重新更新view层数据,model => view
this.subs.forEach(function(watcher){
watcher.update();
})
}
};
//监听者(利用setter监听view => model的数据变化,发出通知更改model数据后再从model => view更新视图所有用到该数据的地方)
function observer(data,vm){
//遍历劫持data下所有属性
Object.keys(data).forEach(function(key){
defineReactive(vm,key,data[key]);
})
}
function defineReactive(vm,key,val){
//新建通知者
var dep = new Dep();
//灵活利用setter与getter访问器
Object.defineProperty(vm,key,{
get(){
//初始化数据更新时将每个数据的watcher添加至队列栈中
if(Dep.target) dep.addSub(Dep.target);
return val;
},
set(newVal){
if(val === newVal) return ;
//初始化后,文档碎片中的虚拟dom已与model层数据绑定起来了
val = newVal;
//同步更新model中data属性下的数据
vm.data[key] = val;
//数据有改动时向通知者发送通知
dep.notify();
}
})
}
//---------------------------------------------------------------
function Vue(options){
this.id = options.el;
this.data = options.data;










