当前位置: 首页 > Web前端 > JavaScript

vue源码守望者阅读记录

时间:2023-03-27 13:53:54 JavaScript

1.首先从computed研究开始functioninitComputed(vm:Component,computed:Object){//首先使用chain方法声明watchers,在vue实例中添加_computedWatchers属性。两者指向同一个对象,用于记录所有的computedconstwatchers=vm._computedWatchers=Object.create(null)//判断是否是服务端渲染constisSSR=isServerRendering()for(constkeyincomputed){constuserDef=computed[key]//计算两个声明Modefunction,object:{get,set}constgetter=typeofuserDef==='function'?userDef:userDef.getif(!isSSR){//为计算属性创建内部观察器。//为每个computedWatcher实例创建,并添加到watchers中,vm._computedWatchers也会添加watchers[key]=newWatcher(vm,getter||noop,noop,computedWatcherOptions)}//判断是否已经存在同名属性在vm上,如果有错误,没有vm的代理,所以this.xxx调用if(!(keyinvm)){defineComputed(vm,key,userDef)}elseif(process.env.NODE_ENV!=='production'){if(keyinvm.$data){warn(`Thecomputedproperty"${key}"isalrreadydefinedindata.`,vm)}elseif(vm.$options.props&&keyinvm.$options.props){warn(`计算属性“${key}”已定义为道具。`,vm)}elseif(vm.$options.methods&&keyinvm.$options.methods){warn(`计算属性“${key}”已定义为方法。`,vm)}}}}2.defineComputed1)首先noop函数是什么?//noop是一个空函数exportfunctionnoop(a?:any,b?:any,c?:any){}2)查看createComputedGetter函数functioncreateComputedGetter(key){//示例:computedName(){return'Mynameis'+this.name}//返回一个getter函数,将计算属性(computedName)的get指向watcher.value,//这里的watcher.value会触发watcher.prototype.get方法,然后triggercomputed依赖responsive变量的get方法,//然后触发dep.depend(),在变量闭包returnfunctioncomputedGetter(){constwatcher=this._computedWatchers中添加watcher到dep实例的subs数组&&this._computedWatchers[key]if(watcher){//computed会默认传递lazy:true,watcher.dirty的初值等于lazy,所以这里为true多次只会触发watcher.get()//evaluate(){//this.value=this.get()//this.dirty=false//}watcher.evaluate()//翻译就是求值,找到函数的值}if(Dep.target){watcher.depend()}returnwatcher.value}}}3)最后,让我们看一下最终的defineComputed函数。这里会用到noop和createComputedGetter,所以提前了解一下//Example:computedName(){return'Mynameis'+this.name}exportfunctiondefineComputed(target:any,key:string,userDef:Object|Function){//判断是否是服务端渲染,这里只研究客户端渲染情况constshouldCache=!isServerRendering()if(typeofuserDef==='function'){//客户端渲染时shouldCache为真,即computedName.get将被设置为createComputedGetter(),//createComputedGetter将返回一个getter方法,见下文sharedPropertyDefinition.get=shouldCache?createComputedGetter(key):createGetterInvoker(userDef)sharedPropertyDefinition。set=noop}else{sharedPropertyDefinition.get=userDef.get?shouldCache&&userDef.cache!==false?createComputedGetter(key):createGetterInvoker(userDef.get):noopsharedPropertyDefinition.set=userDef.set||noop}//如果计算属性是一个函数,设置的时候会报错,这就是为什么我们通常不能设置计算属性if(process.env.NODE_ENV!=='production'&&sharedPropertyDefinition.set===noop){sharedPropertyDefinition.set=function(){warn(`Computedproperty"${key}"wasassignedtobutithasnosetter.`,this)}}//将计算属性(computedName)定义为vm,其中目标是vm(vueinstance)Object.defineProperty(target,key,sharedPropertyDefinition)}