Vue源码-简单的模板解析

type
status
date
slug
summary
tags
category
icon
password
Status
📌
Vue 主要在 <template> 标签中编写 DOM 结构,除了静态的 html 标签,还包含指令、插槽、组件、表达式等更丰富的内容。这期简单解析一下 Vue 中模板的原理。

模板语法

模板语法允许我们声明式地将数据绑定到对应 DOM 节点上,在渲染时,JavaScript 会将变量值或计算出的表达式结果替换掉声明部分。较为常见的模板语法有mustcache风格的{{}} 以及DSL风格的html dsl等。
mustcache为例,比较简单的模板语法可以使用正则匹配的方式,替换掉{{}},通过new Function创建一个render函数传参,实现文本插值。对循环等指令,同样可以通过这样解析替换实现,这里未给出。
Vue1 最核心的实现就是基于这种简单地处理 token 流实现,然而对于比较复杂的渲染,解析的次数会逐渐变多,带来性能问题。
于是很快诞生的 Vue2,引入了虚拟 DOM,即将真实 DOM 解析成 AST(Abstract Syntax Tree),方便后续对模板进行处理,减少了多次解析字符串带来的性能消耗,同时将HTML变成一棵树的数据结构之后更加方便于遍历。
例如下面给出的这段 HTML 代码:
解析成的最简单的 AST:(parent 为父节点引用,暂不列出)
基于 AST 的模板语法需要解析 HTML 成为 AST,然后将 AST 转化为字符串,将字符串作为函数执行,这个过程依旧需要用到 Function,下边的例子只是借助了 JavaScript 取得 DOM 结构生成 AST,没有自行解析 HTML。
虽然看起来最后都需要使用Function去处理字符串,而得到 AST 后还需要解析HTML然后再拼接字符串,增加了计算的时间,但是如果仅仅是完全基于处理字符串的方式实现的模板语法,在数据进行变更时都需要进行render,每次render的时候都需要重新渲染整个 DOM。
虽然在上边的简单实现中AST也是重新渲染了整个模版,但目前主流的框架例如Vue就是基于AST的方式,首先解析templateAST,然后对于AST进行静态节点标记,通过重用已标记静态的节点跳过比对,从而进行渲染优化,然后生成虚拟 DOM。当数据进行变更时虚拟 DOM 会进行diff算法的比对,找到数据有变更的节点,然后进行最小化渲染,这样就不需要在数据变更时将整个模板进行渲染,从而增加了渲染的效率。
 
  • Twikoo

© 2021-2024 Tabing | 萌ICP备20240819号