解析就是将模版解析成AST。
<div id="app">
<p>{{num}}</p>
</div>
比如下面这个代码,然后转成AST之后是这个样子。
它是用javascript对象来描述一个接待您,一个对象表示一个节点。对象中的属性用来保存节点所需的各种数据。
比如parent属性保存了父节点的描述对象,children属性是一个数组,里面保存了一些子节点的描述对象,type属性表示一个节点的类型。
很多独立的节点通过parent属性和children属性连在一起。就变成了一个树。这个就是AST。
解析器内部运行原理
解析器内部分为好几个子解析器,比如html解析器、文本解析器和过滤器解析器。
里面最重要的是html解析器,在解析html过程中会不断触发各种钩子函数。这些钩子函数包括开始标签钩子函数,结束标签钩子函数,文本钩子函数以及注释钩子函数。
这是代码,我们举个例子,
<div id="app">
<p>我是Berwin</p>
</div>
当上面这个模版被html解析器解析时,所触发的钩子函数依次是:parseStartTag,handleStartTag,advance,parseEndTag。
也就是说解析器从前往后解析,遇到<div>
时,会触发一个标签开始的钩子函数,parseStartTag,然后解析到<p>
时,又触发一次钩子函数parseStartTag。接着是到文本,
if (options.chars && text) {
options.chars(text, index - text.length, index);
}
然后解析到</p>
,触发结束钩子函数,parseEndTag,再到</div>
,此时又触发一次标签结束钩子函数。解析结束。
构建AST节点
在handleStartTag中,我们构建AST节点。
export function createASTElement(
tag: string,
attrs: Array<ASTAttr>,
parent: ASTElement | void
): ASTElement {
return {
type: 1,
tag,
attrsList: attrs,
attrsMap: makeAttrsMap(attrs),
rawAttrsMap: {},
parent,
children: []
}
}
通过这个函数来构建ast节点。