Vue从模板到视图

先讲讲大概流程

 

很清晰的可以知道,模板经过模板编译就可以生成渲染函数。生成渲染函数的过程,模板先通过解析器生成AST树,然后经过优化器标记静态节点,然后再通过代码生成器,生成渲染函数可执行代码。

渲染函数执行之后,就会一个新的vnode,先将这个新的vnode缓存,然后将新的vnode和旧的vnode做比较,找到变化的节点,然后进行视图的渲染。

 

模板编译

 模板先通过解析器(html解析器,文本解析器,过滤器解析器)将模板转化成AST树(AST是用对象来描述节点的)

模板解析html解析器,通过维护一个栈来体现节点之间的嵌套关系,解析的方法是通过多次截取,然后判断

如果第一个字符是'<'

如果解析遇到的标签是开始标签,就将这个节点放入栈中,构建一个元素类型的AST节点。(要判断是否是自闭合标签)

如果遇到的是结束标签,就将在栈顶的这个标签的开始标签弹出(通过这个方法也可以验证,各元素之间的结构是否有问题,如果结束标签和栈顶的元素不同,就报错)

如果遇到的是注释,不进栈。直接创建一个注释类型的AST标签。

第一个字符不是'<'

说明就是文本,如果文本中存在变量,文本解析器就来进行解析。如果文本中不存在变量,就不需要解析器。

 

解析器生成AST树之后,通过优化器对AST树进行优化

优化器找到AST中的所有静态节点,然后做上标记。

优化的原理是静态节点除了首次渲染需要生成节点以外,重新渲染并不会生成新的节点,静态节点是不需要比较,直接克隆,不需要patch,可以节省性能。

过程:要标记静态节点和静态根节点

如果父节点的所有子节点都是静态节点,就标记为静态根节点。但是如果只有一个子元素是静态节点,就不标记。因为在这种情况下标记的成本大于收益

 

对AST优化之后,就是执行代码的生成,通过代码生成器

代码生成的过程是一个字符串拼接的过程,元素节点_c,文本节点_v,注释节点_e

 

patch

渲染函数生成之后,执行,就会生成newVnode,先对生成的newVnode进行缓存,下次更新的时候就作为oldVnode来比较

然后就是newVnode和oldVnode比较的过程

所有的渲染都以newVnode为准

如果是静态节点直接克隆

如果newVnode中没有这个节点,就删除。

如果oldVnode中没有该节点,直接创建,然后插入

如果都有,就比较子节点是否相同

新旧树的比较,已经标记的点标记为已处理,如果新树中有新增的点,直接就添加到所有未处理的节点的前面。

节点的移动也是这个思路,如何确定移动的思路,因为前面所有的点都处理过了。

所有子节点的遍历优化

新前(新树中第一个未处理的节点),旧前(旧树中第一个未处理的节点)

新后(新树中最后一个未处理的节点),旧后(旧树中最后一个未处理的节点)

新后,旧前

新前,旧后

这样的比较,如果还是没有找到就遍历。这样就需要两个指针来标记位置,开始指针和结束指针,然后向中间移动。while(start < end)

posted @ 2020-10-08 15:52  kkkllo  阅读(206)  评论(0)    收藏  举报