前后端模板引擎选型

讨论模板引擎,就是讨论api模式。至于双向绑定,以及是否使用vdom,完全是另外一个层面的事情。经过多种层次的实践,笔者建议,干脆选一种最方便模板用作创作,另外的框架使用的模板则用这种模板自动翻译或生成。

【早期CGI系,原始的拼接字符串风格;简单插值可使用多行模板字符串】

1
2
3
4
5
6
7
8
9
10
11
if ( list.length ) {
html+='<ol>';
for ( n=0; n<list.length; ++n ) {
html+=`
<li>
${ list[n] }
</li>
`;
}
html+='</ol>';
}

【亲民XSP系(如PHP/ASP/JSP),拼接字符串模式的反转语法(糖);逻辑视觉比例过高】

1
2
3
4
5
6
7
8
9
<% if ( list.length ) { %>
<ol>
<% for ( n=0; n<list.length; ++n ) { %>
<li>
<%= list[n] %>
</li>
<% } %>
</ol>
<% } %>

【简约语法(如EJS),再度简约;高级语法有限,通常难自定义拓展】

1
2
3
4
5
6
7
8
9
{{#if list.length}}
<ol>
{{#each list item}}
<li>
{{ item }}
</li>
{{/each}}
</ol>
{{/if}}

【丧心病狂的创造语法(如Jade);完全新语法,大量强大功能,极度简洁,投奔与否见仁见智】

1
2
3
4
- if list.length
ol.
- each item in list
li= item

【返璞归真(如Vue;确切说是如Vue的模板解读方式),基于DOM属性的指令语法,前端模板优势一目了然】

1
2
3
4
5
<ol v-if="list.length">
<li v-for="item in list">
{{ item }}
</li>
</ol>

【另辟蹊径,回归完全亲和的JS胶水语法,笔者作为选用Vue的服务器端补充(以及面向未来的多客户端通用原型模板;不过还不确定是否应当合并IE6-9和先进浏览器模板,还是索性分离更为实用);任意拓展、组件即数据即函数。】

1
2
3
4
5
ol({v_if:`list.length`},
li({v_for:`item in list`},
'{{ item }}'
)
)

更完整的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template(
'<!DOCTYPE html>',
html(
head(
meta({charset:'utf-8'})
),
body(
'原始字符',
'{{ $数据.$转义变量 }}',
ol({v_if:`'length' in $数据.$列表`,v_bind$title:`$数据.$标题`},
li({v_for:`_值 in $数据.$列表`,v_bind$title:`$index`},
'{{ _值 }}'
)
),
template({v_for:`_便捷临时变量 in {_:$数据.$浅层.$深层}`},
'{{ _便捷临时变量 }}'
)
)
)
)

唯一的问题是……如果说XSP系是阳火旺的话,那这种方案就可以说是阴火旺了。js实现的html结构过于简练,反而和变量混淆不清,和XSP逻辑比重过多,殊途同归。