浅谈vue中.vue文件解析流程

网友投稿 330 2023-02-07


浅谈vue中.vue文件解析流程

我们平时写的 .vue 文件称为 SFC(Single File Components),本文介绍将 SFC 解析为 descriptor 这一过程在 vue 中是如何执行的。

vue 提供了一个 compiler.parseComponent(file, [options]) 方法,来将 .vue 文件解析成一个 descriptor:

// an object format describing a single-file component.

declare type SFCDescriptor = {

template: ?SFCBlock;

script: ?SFCBlock;

styles: Array;

customBlocks: Array;

};

文件入口

解析 sfc 文件的入口在 src/sfc/parser.js 中,该文件 export 了 parseComponent 方法, parseComponent 方法用来对单文件组件进行编译。

接下来我们看看 parseComponent 方法都做了哪些事情。

parseComponent 方法

function start(tag, attrs, unary, start, end,){

}

function end(tag, start, end){

}

parseHTML(content, {

start,

end

})

parseComponent 方法中定义了 start``end 两个函数,之后调用了 parseHTML 方法来对 .vue 文件内容践行编译。

那么这个 parseHTML 方法是做啥的呢?

parseHTML 方法

该方法看名字就知道是一个 html-parser,可以简单理解为,解析到每个起始标签时,调用 TBFNPczGvToption 中的 start;每个标签结束时,调用 option 中的 end。

对应到这里,就是分别调用 parseComponent 方法中定义的 start 和 end 函数。

在 parseComponent 中维护一个 depth 变量,在 start 中将 depth++ ,在 end TBFNPczGvT中 depth-- 。那么,每个 depth === 0 的标签就是我们需要获取的信息,包含 template、script、style 以及一些自定义标签。

start

每当遇到一个起始标签时,执行 start 函数。

1、记录下 currentBlock。

每个 currentBlock 包含以下内容:

declare type SFCBlock = {

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 { // custom blocks

sfc.customBlocks.push(currentBlock)

}

end

每当遇到一个结束标签时,执行 end 函数。

1、如果当前是第一层标签(depth === 1),并且 currentBlock 变量存在,那么取出这部分text,放在 currentBlock.content 中。

if (depth === 1 && currentBlock) {

currentBlock.end = start

let text =http:// deindent(content.slice(currentBlock.start, currentBlock.end))

// pad content so that linters and pre-processors can output correct

// line numbers in errors and warnings

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 等库来做的。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:电脑连接共享文件夹(电脑连接共享文件夹没反应)
下一篇:Java基于命令模式实现邮局发信功能详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~