什么是juicer(what)
Juicer 是一个高效、轻量的前端 (Javascript) 模板引擎,使用 Juicer 可以是你的代码实现数据和视图模型的分离(MVC)。 除此之外,它还可以在 Node.js 环境中运行。
通过这个例子直观的展现出前端模板引擎的好处所在,这么做能够完全剥离html和代码逻辑,便于多人协作和后期的代码维护。
一个完善的模板引擎应该兼顾这几点
- 语法简明
- 执行效率高
- 安全性
- 错误处理机制
- 多语言通用性
a.语法
- 循环: {@each}…{@/each}
- 判断:{@if}…{@else if}…{@else}…{@/if}
- 变量(支持函数):${varname|function}
- 注释:{# comment here}
b.安全性
- juicer对数据输出做了安全转义,如果不想被转义,可以使用$${varname}。
c.错误处理
- 如果没有错误处理机制,在模版编译和渲染出现错误的时候,js会停止加载
- juicer的错误处理机制会在出现错误时跳过当前步骤并在控制台上提示Juicer Compile Exception: Unexpected token ,”,不会因为错误导致后续js无法执行
实现原理
- 对模版引擎进行语法分析
- 分析后生成原生的javascript代码字符串
- 将生成的代码转化成可重用的function
使用方法
- 编译模版并根据所给的数据立即渲染出结果
juicer(tpl, data);
- 仅编译模版,暂不渲染
var compiled_tpl = juicer(tpl);
- 根据给定的数据,对之前编译好的模板进行数据渲染.
var compiled_tpl = juicer(tpl);
var html = compiled_tpl.render(data);
5.自定义模板语法边界符,下边是 Juicer 默认的边界符。你可以借此解决 Juicer 模板语法同某些后端语言模板语法冲突的情况.
juicer.set({
'tag::operationOpen': '{@',
'tag::operationClose': '}',
'tag::interpolateOpen': '${',
'tag::interpolateClose': '}',
'tag::noneencodeOpen': '$${',
'tag::noneencodeClose': '}',
'tag::commentOpen': '{#',
'tag::commentClose': '}'
});
语法
a. ${变量}
使用 ${} 输出变量值,其中 _ 为对数据源的引用(如 ${_},常用于数据源为数组的情况)。支持自定义函数(通过自定义函数你可以实现很多有趣的功能,类似 ${data|links} 就可以 通过事先定义的自定义函数 links 直接对 data 拼装出 ).
${name}
${name|function}
${name|function, arg1, arg2}
b. 内联辅助函数 {@helper} ... {@/helper}
{@helper numberPlus}
function(number) {
return number + 1;
}
{@/helper}
var tpl = 'Number: ${num|numberPlus}';
juicer(tpl, {
num: 123
});
//输出 Number: 124
c. 循环遍历 {@each} ... {@/each}
如果你需要对数组进行循环遍历的操作,就可以像这样使用
each
.
{@each list as item}
${item.prop}
{@/each}
如果遍历过程中想取得当前的索引值,也很方便.
{@each list as item, index}
${item.prop}
${index} //当前索引
{@/each}
d. 判断 {@if} ... {@else if} ... {@else} ... {@/if}
{@each list as item,index}
{@if index===3}
the index is 3, the value is ${item.prop}
{@else if index === 4}
the index is 4, the value is ${item.prop}
{@else}
the index is not 3, the value is ${item.prop}
{@/if}
{@/each}
e. 注释 {# 注释内容}
为了后续代码的可维护性和可读性,我们可以在模板中增加注释.
{# 这里是注释内容}