# 模板语法的简单实现 模板语法允许在`HTML`中之插入`Js`变量以及表达式,当在`Js`中控制`render`的时候能够自动在页面上将变量或者是表达式进行计算并显示,比较常见的模板语法有`mustcache`风格的`{{}}`以及`DSL`风格的`dsl-html`等。 ## AST `AST`抽象语法树,全称为`Abstract Syntax Tree`是源代码的抽象语法结构的树状表现形式,每种源码都可以被抽象成为`AST`,在这里把模板解析成为`AST`,就是将模板的`HTML`结构进行解析,变成一棵附带结构、关系、属性的抽象树。这样做方便后续对模板进行处理,减少了多次解析字符串带来的性能消耗,同时将`HTML`变成一棵树的数据结构之后更加方便于遍历,下面是对于例子中的`HTML`的简单的`AST`。 ```html

1

11
``` ```javascript { type: "tag", tagName: "div", attr: { className: "root" name: "root" }, parent: null, children: [{ type: "tag", tagName: "p", attr: {}, parent: {} /* 父节点的引用 */, children: [{ type: "text", tagName: "text", parent: {} /* 父节点的引用 */, content: "1" }] },{ type: "tag", tagName: "div", attr: {}, parent: {} /* 父节点的引用 */, children: [{ type: "text", tagName: "text", parent: {} /* 父节点的引用 */, content: "11" }] }] } ``` ## 简单实现 对`mustcache`风格的`{{}}`进行简单的实现,仅对于其数据的展示方面有实现,对于其指令例如循环等并未实现。通过处理字符串,将其转换为一个函数并传参执行,即可实现数据的展示。 ```html 模板语法
{{show}}
{{description}}
``` 通过对于字符串的处理并使用`Function`实现模板语法,如果使用正则表达式进行较为完整的过滤,是完全可以生成较为完善的模板语法的处理的,包括`Js`的表达式以及自带指令等,如`mustcache.js`、`layui.js`的`laytpl`模块。基于`AST`的模板语法需要解析`HTML`成为`AST`,然后将`AST`转化为字符串,将字符串作为函数执行,这个过程依旧需要用到`Function`,下边的例子只是借助了`Js`取得`DOM`结构生成的`AST`,没有自行解析`HTML`。 ```html 模板语法
{{show}}
{{description}}
``` 虽然看起来最后都需要使用`Function`去处理字符串,而`AST`还需要解析`HTML`然后再拼接字符串,增加了计算的时间。但是如果仅仅是完全基于处理字符串的方式实现的模板语法,在数据进行变更时都需要进行`render`,每次`render`的时候都需要重新渲染整个`DOM`。 虽然在上边的简单实现中`AST`也是重新渲染了整个模板,但是现在主流的`Js`框架例如`Vue`就是基于`AST`的方式,首先解析`template`为`AST`,然后对于`AST`进行静态节点标记,用以标记静态的节点进行重用跳过比对,从而进行渲染优化,然后生成虚拟`DOM`。当数据进行变更时虚拟`DOM`会进行`diff`算法的比对,找到数据有变更的节点,然后进行最小化渲染,这样就不需要在数据变更时将整个模板进行渲染,从而增加了渲染的效率。 ## 每日一题 - ## 参考 - - -