模板
1 | <ul> |
JS数据
1 | const arr = [ |
打印出的结果为
1 | "<ul> |
从以上的代码可以看出,将结构和数据传入tmpl函数中,就能实现拼接。而tmpl正是我们所说的模板引擎(函数)。接下来我们就来实现一下这个函数。
实现
模板引擎函数实现的本质,就是将模板中HTML结构与JavaScript语句、变量分离,通过Function构造函数 + apply(call)动态生成具有数据性的HTML代码。而如果要考虑性能的话,可以将模板进行缓存处理。
实现一个模板引擎函数,大致有以下步骤:
- 模板获取
- 模板中HTML结构与JavaScript语句、变量分离
- Function + apply(call)动态生成JavaScript代码
- 模板缓存
- 模板获取
一般情况下,我们会把模板写在script标签中,赋予id属性,标识模板的唯一性;赋予type=’text/html’属性,标识其MIME类型为HTML,如下
1 | <script type="text/html" id="template"> |
在模板引擎中,选用<% xxx %>
标识JavaScript语句,主要用于流程控制,无输出;<%= xxx %>
标识JavaScript变量,用于将数据输出到模板;其余部分都为HTML代码。(与EJS类似)。
注:如果是模板放在一个独立的文件,可以先获取<script>
的scr
属性,再ajax
请求获取文件内容。
- HTML结构与JavaScript语句、变量分离
主要是通过replace函数替换实现的。说明一下主要流程:
- 创建数组arr,再拼接字符串arr.push(‘
- 遇到换行回车,替换为空字符串
- 遇到<%时,替换为’);
- 遇到>%时,替换为arr.push(‘
- 遇到<%= xxx %>,结合第3、4步,替换为’); arr.push(xxx); arr.push(‘
最后拼接字符串’); return p.join(‘’);
在代码中,需要将第5步写在2、3步骤前面,因为有更高的优先级,否则会匹配出错。如下
1 | let tpl = '' |
如果模板中出现了单引号,那会影响整个函数的执行的。还有一点,如果出现了 \ 反引号,会将单引号转义了。所以需要对单引号和反引号做一下优化处理。
- 模板中遇到 \ 反引号,需要转义
- 遇到 ‘ 单引号,需要将其转义
转换为代码,即为
1 | str.replace(/\\/g, '\\\\') |
1 | let tpl = '' |
1 |
|