本文总结了 3 种实现模板引擎的方式,最后将编写一个 类似于 underscore.template 的模板插件
replace
介绍
replace 是字符串提供的一个超级强大的方法,这里只介绍简单的使用,更多详细的语法参见下面提供的链接
- 一参可为
字符串
或正则
:- 为正则时有两种情况:
普通匹配模式
和全局匹配模式
:- 全局匹配模式下,若二参为函数,则该函数在每次匹配时都会被调用
- 为正则时有两种情况:
- 二参可为
字符串
或一个用于生成字符串的函数
:- 当为字符串时:
- 可在字符串中使用 特殊替换字符 ($n …)
- 当为函数时:
- 函数中不能用 特殊替换字符
- 一参为正则匹配的文本
- 倒数第二参为匹配到的子字符串在原字符串中的偏移量
- 最后一参为被匹配的原始字符串
- 其余参数为正则中每个分组匹配到的文本
- 当为字符串时:
1 2 3 4 5 6 7 8 9 10 11 |
|
以下是各种情况下的具体案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
原理
先在模板中预留占位( ),再将对应的数据填入
实现
要求1: 可填充简单数据
1 2 |
|
要求2: 可填充嵌套数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
最终代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
优缺点
- 优点: 简单
- 缺点: 无法在模板中使用表达式,所有数据都得事先计算好再填入,且填充的数据应为基础类型,灵活性差,难以满足复杂的需求
资料
模板字符串
介绍
- 模板字符串包裹在 反引号(Esc按钮下面那个) 中,其中可通过 ${} 的语法进行插值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
案例
资料
new Function
介绍
- Function 是 js 提供的一个用于构造 Function 对象的构造函数
1 2 3 4 5 6 7 8 |
|
实现
- 大多数前端模板引擎都是用这种方式实现的,其原理在于运用了 js Function 对象可将字符串解析为函数的能力。
- 一个普通模板引擎的工作步骤大致如下
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
- 由此可见,只要将 {@ @} 里的字符串内容生成 js 语句,而其余内容之前加上 一个 ‘tpl += ’ 即可。
实现代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
ok, 一个最最简单的模板引擎就已经完成了,支持在模板中嵌入 js 语句,虽然只有不到10行,但还是挺强大的对不。
拓展
实现模板类
为了能够更好的使用,将前面的代码抽成一个类。
- 需求:
- 标识符格式有可能和后端模板引擎冲突,因此应实现成可配置的
{@ @}
: 用于嵌套逻辑语句- ``: 用于嵌套变量或表达式
- 在模板中应能添加注释,注释有两种:
<!-- -->
: 会输出{# #}
: 这种注释会在编译时被忽略,即只在模板中可见
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
注释的 BUG
上面的代码在解析一些特殊模板注释(如下)时会出错 <!-- -->
(由于注释中有标识符,因此会将 a 作为变量解析,会报未定义错误)
解决: 在解析注释时,如注释里有标识符,则将其先替换成其他符号,等语句变量的解析完成时,再替换回来
1 2 3 4 5 6 |
|
语法模式
在模板里写 js 好烦呀,各种 ‘{’ 乱飞,有些模板提供了更好看的语法:
1 2 3 4 5 6 7 8 9 10 11 |
|
其实就是在解析语句时多做一些处理而已:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
过滤器
- 很多模板引擎中都有提供很多好用的过滤器:
- 字符串转大写的过滤器:
<p>tpl</p> => <p>TPL</p>
- 字符串转大写的过滤器(支持流式):
<p>tpl</p>
- 字符串转大写的过滤器:
现在我们来编写这个拓展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
- 至此该模板引擎就完成了,总结下功能:
- 支持在模板中使用 js 语句
- 支持自定义标识符
- 支持更简洁的语法模式
- 支持过滤器