浅谈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等库来做的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。