vue的渲染过程
Vue的模板编译在$mount之后,通过compile方法,经过parse、optimize、generate方法,最后生成render function来生成虚拟DOM,虚拟DOM通过diff算法,来更新DOM。
具体功能如下:
- parse 函数解析 template
- optimize 函数优化静态内容
- generate 函数创建 render 函数字符串
parse
在了解 parse 的过程之前,我们需要了解 AST,AST 的全称是 Abstract Syntax Tree,也就是所谓抽象语法树,用来表示代码的数据结构。在 Vue 中我把它理解为嵌套的、携带标签名、属性和父子关系的 JS 对象,以树来表现 DOM 结构。
vue中的ast类型有以下3种
ASTElement = { // AST标签元素
type: 1;
tag: string;
attrsList: Array<{ name: string; value: any }>;
attrsMap: { [key: string]: any };
parent: ASTElement | void;
children: Array<ASTNode>
...
}
ASTExpression = { // AST表达式 {
{ }}
type: 2;
expression: string;
text: string;
tokens: Array<string | Object>;
static?: boolean;
};
ASTText = { // AST文本
type: 3;
text: string;
static?: boolean;
isComment?: boolean;
};
通过children字段来形成一种层层嵌套的树状结构。vue中定义了许多正则(判断标签开始、结束、属性、vue指令、文本),通过对html内容进行递归正则匹配,对满足条件的字符串进行截取。把字符串类型的html转换位AST结构
parse函数的作用就是把字符串型的template转化为AST结构
如,假设我们有一个元素<div id=“test”>texttext</div>,在 parse 完之后会变成如下的结构并返回:
ele1 = {
type: 1,
tag: "div",
attrsList: [{name: "id", value: "test"}],
attrsMap: {id: "test"},
parent: undefined,
children: [{
type: 3,
text: 'texttext'
}
],
plain: true,
attrs: [{name: "id", value: "'test'"}]
}
那么它具体是怎么解析、截取的呢?
举个例子
<div>
<p>我是{
{name}}</p>
</div>
他的截取过程,主要如下
// 初始
<div>
<p>我是{
{name}}</p>
</div>
// 第一次截取剩余(包括空格)
<p>我是{