浅谈vue中.vue文件解析流程
我们平时写的.vue文件称为SFC(SingleFileComponents),本文介绍将SFC解析为descriptor这一过程在vue中是如何执行的。
vue提供了一个compiler.parseComponent(file,[options])方法,来将.vue文件解析成一个descriptor:
//anobjectformatdescribingasingle-filecomponent. declaretypeSFCDescriptor={ template:?SFCBlock; script:?SFCBlock; styles:Array; customBlocks:Array ; };
文件入口
解析sfc文件的入口在src/sfc/parser.js中,该文件export了parseComponent方法,parseComponent方法用来对单文件组件进行编译。
接下来我们看看parseComponent方法都做了哪些事情。
parseComponent方法
functionstart(tag,attrs,unary,start,end,){ } functionend(tag,start,end){ } parseHTML(content,{ start, end })
parseComponent方法中定义了start``end两个函数,之后调用了parseHTML方法来对.vue文件内容践行编译。
那么这个parseHTML方法是做啥的呢?
parseHTML方法
该方法看名字就知道是一个html-parser,可以简单理解为,解析到每个起始标签时,调用option中的start;每个标签结束时,调用option中的end。
对应到这里,就是分别调用parseComponent方法中定义的start和end函数。
在parseComponent中维护一个depth变量,在start中将depth++,在end中depth--。那么,每个depth===0的标签就是我们需要获取的信息,包含template、script、style以及一些自定义标签。
start
每当遇到一个起始标签时,执行start函数。
1、记录下currentBlock。
每个currentBlock包含以下内容:
declaretypeSFCBlock={ type:string; content:string; start?:number; end?:number; lang?:string; src?:string; scoped?:boolean; module?:string|boolean; };
2、根据tag名称,将currentBlock对象在返回结果对象中。
返回结果对象定义为sfc,如果tag不是script,style,template中的任一个,就放在sfc.customBlocks中。如果是style,就放在sfc.styles中。script和template则直接放在sfc下。
if(isSpecialTag(tag)){ checkAttrs(currentBlock,attrs) if(tag==='style'){ sfc.styles.push(currentBlock) }else{ sfc[tag]=currentBlock } }else{//customblocks sfc.customBlocks.push(currentBlock) }
end
每当遇到一个结束标签时,执行end函数。
1、如果当前是第一层标签(depth===1),并且currentBlock变量存在,那么取出这部分text,放在currentBlock.content中。
if(depth===1&¤tBlock){ currentBlock.end=start lettext=deindent(content.slice(currentBlock.start,currentBlock.end)) //padcontentsothatlintersandpre-processorscanoutputcorrect //linenumbersinerrorsandwarnings if(currentBlock.type!=='template'&&options.pad){ text=padContent(currentBlock,options.pad)+text } currentBlock.content=text currentBlock=null }
2、depth--。
得到descriptor
在将.vue整个遍历一遍后,得到的sfc对象即为我们需要的结果。
生成.js?
compiler.parseComponent(file,[options])得到的只是一个组件的SFCDescriptor,最终编译成.js文件是交给vue-loader等库来做的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。