前言在Vue中,data选项是个好东西,把数据丢进去,你可以在Vue组件的任何地方通过this来读取数据中的数据数据。但要避免滥用它来读取数据中的数据。至于哪些地方可以避免滥用,滥用会造成什么后果,本专栏将一一揭晓。1.使用this读取data中数据的过程在vue源码中,data中的数据会添加getter函数和setter函数,转换成响应式的。getter函数代码如下:;if(Array.isArray(value)){dependArray(value);}}}returnvalue}使用this读取data中的数据时,会触发getter函数,其中varvalue=getter?getter.call(obj):val;获取到值后执行返回值,达到读取数据的目的。但是中间还有一段代码,其中会通过一系列复杂的逻辑操作来收集依赖。这里只需要知道Dep.target存在时就会收集依赖。这里可以得出一个结论。当Dep.target存在时,用这个读取data中的数据会收集依赖。如果滥用这个来读取数据中的数据,就会重复收集依赖,导致性能问题。2、Dep.target什么时候存在?Dep.target由依赖分配。依赖也称为Watcher(监听器)或订阅者。Vue中有三种依赖,其中两种很常见,分别是watch(监听器)和computed(计算属性)。还有一个隐藏的dependency-renderingWatcher,它是在模板第一次渲染时创建的。dep.target在创建依赖的时候被赋值,依赖的构造函数是Watcher创建的。lue=this.lazy?undefined:this.get();};Watcher.prototype.get=functionget(){pushTarget(this);try{value=this.getter.call(vm,vm);}catch(e){}functionWatcher(vm,expOrFn,cb,options,isRenderWatcher){//...if(typeofexpOrFn==='function'){this.getter=expOrFn;}else{this.getter=parsePath(expOrFn);}this.vareturnvalue};Dep.target=null;vartargetStack=[];functionpushTarget(target){targetStack.push(target);Dep.target=target;}在构造函数的最后会执行Watcher的实例方法get,实例方法中在pushTarget(this)中赋给Dep.target的值在get中执行。依赖是在Vue页面或组件第一次渲染时创建的,所以性能问题应该是第一次渲染慢导致的。3.在哪里滥用this读取data中的数据当Dep.target存在的时候执行滥用this读取data中的数据的代码会导致性能问题,所以需要搞清楚这些代码写在哪里才能执行,换句话说,找出在数据中滥用此读取数据的位置会导致性能问题。第二节介绍了Dep.target赋值后,会执行value=this.getter.call(vm,vm),其中this.getter是一个函数,所以如果用this读取data数据,它会收集依赖项,如果被滥用,会导致性能问题。this.getter是在创建依赖的时候赋值的,每个依赖的this.getter都不一样。让我们一一介绍。watch(listener)依赖的this.getter是parsePath函数,它的函数参数是要监听的对象。varbailRE=newRegExp(("[^"+(unicodeRegExp.source)+".$_\\d]"));functionparsePath(path){if(bailRE.test(path)){return}varsegments=path.split('.');returnfunction(obj){for(vari=0;i {{a}}{{b}}
