Vue2.X如何使用Object.defineProperty()实现数据绑定上一篇写了Object.defineProperty的使用,这篇文章说说Vue如何使用这个方法来实现数据绑定。首先,简化Vue中的核心方法defineReactivefunctiondefineReactive(obj,key,val,cb){vardep=newDep();Object.defineProperty(obj,key,{enumerable:true,configurable:true,get:()=>{/*....依赖集合等....*/dep.depend()returnval},set:newVal=>{val=newVal;/*Triggercallback*/dep.notify()}})}Vue通过defineReactive方法监听待观察对象的各个属性。dep对象相当于一个调度中心。如果有数据使用该属性,会自动将该属性采集到调度中心。如果某个属性发生变化,它会通知调度中心更新视图。再看看dep方法及其功能。比较简单:1.存储订阅者2.添加订阅者functionDep(){//所有的watcher都放在这里统一管理this.subs=[]}Dep.target=null;//通知视图更新notify的notifydom的方法Dep.prototype.notify=function(){//this.subs存储了watcherthis.subs.forEach(sub=>{//sub是一个Watcher专门调用一个Watcher的update方法sub.update()})}//添加订阅者的方法Dep.prototype.addSub=function(sub){this.subs.push(sub)}订阅者主要有两种方法;1.触发获取属性,顺便添加自己去调度中心2.更新更新视图//具体订阅者Watcher//传入一个vue实例,监听的属性,处理回调函数函数Watcher(vm,prop,callback){this.vm=vm;这个.$prop=prop;this.value=this.get();this.callback=回调;}//添加观察者获取属性的get方法。当有属性access/set时,订阅者将subscribe放入调度中心Watcher.prototype.get=function(){Dep.target=this;//获取属性值constvalue=this.vm.$data[this.$prop];returnvalue}//添加watcher更新视图的方法Watcher.prototype.update=function(){//当属性值改变时,执行该方法并尝试更新constvalue=this.vm.$data[this.$道具];this.callback(this.value)}所以当外界读取数据时,会调用watcher,从而触发getter将watcher添加到Dep依赖中中间(即编译过程收集依赖)当数据发生变化时,会触发setter向Dep中的依赖(watchers)发送通知。(在交互过程中,调度中心通知用户快速更新)。Watcher收到通知后,会向外界发送通知。对外的变化通知可能会触发更新尝试,或者触发用户的回调函数。(订阅者修改相应的值,页面参数相应响应)当然,这只是单向绑定。双向绑定意味着视图更改数据。这个比较简单。在编译过程中将标签绑定到输入。方法,只需修改相应的数据即可。有来有回,实现了双向绑定。
