先看看别人画的图。我的手绘图其实一共是3+1+view渲染模块3:observer:listenervue2.0使用Object.defineProty,vue3.0使用proxywatcher:Subscribercompile:ParserDep:SubscriberCollectorview:Renderdom通过看如图,先找到几个路径a,observer-->Dep-->watcher-->viewb,compile-->watcher-->Depc,compile-->viewc路径最简单,主要实现c是解析v-model等指令,初始化到视图层。b路径compile-->watcher形成一个初始化的订阅者,watcher-->Dep订阅者添加到订阅者中,其实是在observer阶段添加的eg:vue2.0的Object.defineProty的get方法是的,但是为什么没有观察者循环呢?设计者使用了兼容的写法,在数据监听器的观察者方法中强行调用了Object.defineProty的get方法。一个路径observer-->Dep-->watcher是通知变化的。这个阶段eg:vue2.0的Object.defineProty的set方法被触发。最后,watcher-->view的变化体现在view层,不难发现。view层只有complie和watcher。一种是将模板初始化到视图层,另一种是更新后更新到视图层。无论哪条路径到达视图层,实际上都是操作dom上的原始事件(观察者在第三个参数回调函数中改变视图),如:node.textContent=typeofvalue=='undefined'?'':value;看watcher的大致实现:functionWatcher(vm,exp,cb){this.cb=cb;这个.vm=虚拟机;//vm数据对象this.exp=exp;//exp数据对象的键keythis.value=this.get();//将自己添加到订阅者的操作}Watcher.prototype={update:function(){this.run();},运行:function(){varvalue=this.vm.data[this.exp];varoldVal=this.value;if(value!==oldVal){this.value=value;this.cb.call(this.vm,value,oldVal);}},get:function(){Dep.target=this;//自己缓存varvalue=this.vm.data[this.exp]//在监听器中强制执行get函数Dep.target=null;//释放自己返回值;}};了解了这个电路之后,再对电路实现的逻辑一一了解,就很容易理解和记忆了。
