// 控制着observer是否能生成 ob 对象exportfunctiontoggleObserving(value:boolean){
shouldObserve = value
}// 为value 新增__ob__ ,每个ob关联一个dep // value为数组时会修改其原型链上的方法,使其某些方法可以触发更新,并为其每个元素进行 observer// value是对象则会针对每个值 defineReactiveexportclassObserver{
value:any;
dep: Dep;
vmCount:number;// number of vms that have this object as root $dataconstructor(value:any){}walk(obj: Object){}observeArray(items:Array<any>){}}// 由shouldObserve 与类型判断控制是否生成 ob , 如果生成或已有ob,则返回exportfunctionobserve(value:any, asRootData:?boolean): Observer |void{}/**
* Define a reactive property on an Object.
* 配置obj[key]属性为响应式,会获取其原本的 getter, setter
* 响应式的属性当被取值时(getter),会检查全局target,如果当前被watch了,则会收集watcher,如果val是数组则会让每个元素都一并收集
* 响应式的属性当被赋值时(setter(val))会通知所有收集的watcher
* 注:当对obj不存在的key进行响应式时,将会没有getter,setter,只改闭包中的值
*/exportfunctiondefineReactive(
obj:any,
key:string,
val?:any,
customSetter?:Function,
shallow?:boolean){}/**
* Set a property on an object. Adds the new property and
* triggers change notification if the property doesn't
* already exist.
* 更改obj/arr或新增响应式属性
*/exportfunctionset(target:any[]|any, key:string|number, val:any):any{}/**
* Delete a property and trigger change if necessary.
*/exportfunctiondel(target:any|any[], key:any){}
let uid =0exportdefaultclassWatcher{
vm: Component;
expression:string;cb:(value?:any, oldValue?:any)=>void;
id:number;// options
deep:boolean;
user:boolean;
lazy:boolean;
sync:boolean;
dirty:boolean;//状态
active:boolean;// 记录着被哪些依赖收集
deps:Array<Dep>;
newDeps:Array<Dep>;
depIds: SimpleSet;
newDepIds: SimpleSet;
before?:Function;getter:()=>any;
value:any;constructor(
vm: Component,
expOrFn:string|Function,cb:(value?:any, oldValue?:any)=>void,
options?: WatcherOption |void,
isRenderWatcher?:boolean){// ...this.value =this.lazy
?undefined:this.get()}/**
* Evaluate the getter, and re-collect dependencies.
* 当前watcher入栈,获取expOrFn 对应的值,并且让其内部的响应式属性收集当前watcher,形成绑定关系
*/get():any{pushTarget(this);
value =this.getter.call(vm, vm)if(this.deep){traverse(value)}popTarget()this.cleanupDeps()return value
}/**
* Add a dependency to this directive.
*/addDep(dep: DepInstance){}/**
* Clean up for dependency collection.
* 清除久依赖,将新依赖转为旧依赖
*/cleanupDeps(){}/**
* Subscriber interface.
* Will be called when a dependency changes.
* 三种情况更新
*/update(){/* istanbul ignore else */if(this.lazy){this.dirty =true;}elseif(this.sync){this.run();}else{queueWatcher(this);}}/**
* Scheduler job interface.
* Will be called by the scheduler.
* 触发 get() 更新 value , 并触发 cb.call(vm,val,oval) (cb对于RenderWatcher无意义)
*/run(){}/**
* Evaluate the value of the watcher.
* This only gets called for lazy watchers.
*/evaluate(){this.value =this.get()this.dirty =false}/**
* Depend on all deps collected by this watcher.
*/depend(){let i =this.deps.length
while(i--){this.deps[i].depend()}}/**
* Remove self from all dependencies' subscriber list.
*/teardown(){if(this.active){// remove self from vm's watcher list// this is a somewhat expensive operation so we skip it// if the vm is being destroyed.if(!this.vm._isBeingDestroyed){remove(this.vm._watchers,this)}let i =this.deps.length
while(i--){this.deps[i].removeSub(this)}this.active =false}}}
traverse
方法/类
作用
traverse(val: any)
遍历对象(收集当前target),如果存在ob,则将其ob.dep.id记录,防止死循环
scheduler
方法/类
作用
queueWatcher(watcher: WatcherInstance)
将watcher加入队列中,下个周期开始触发watcher.run
flushSchedulerQueue ()
排序并触发watcher队列
let waiting =false;let flushing =false;let index =0;let has:{[key:number]:boolean}={};// 循环 watcher 的id记录let circular:{[key:number]:number}={}exportfunctionqueueWatcher(watcher: WatcherInstance){}//如果a,b两个watcher 互相影响,则会造成死循环,用circular计数,防止崩溃functionflushSchedulerQueue()