📑 快速导航
1. Expressions 表达式
1.1 基础变量输出
Handlebars表达式使用双大括号 {{}} 包裹,用于输出变量值:
示例:输出简单变量
{{! 模板 }}
<h1>{{title}}</h1>
<p>{{description}}</p>
{{! 数据 }}
{
"title": "Handlebars 语法指南",
"description": "学习Handlebars模板语法"
}
{{! 输出 }}
<h1>Handlebars 语法指南</h1>
<p>学习Handlebars模板语法</p>
1.2 嵌套路径访问
使用点号或方括号访问嵌套对象的属性:
{{! 模板 }}
<p>{{user.name}}</p>
<p>{{user.email}}</p>
<p>{{post["title"]}}</p>
{{! 数据 }}
{
"user": {
"name": "张三",
"email": "zhangsan@example.com"
},
"post": {
"title": "我的第一篇文章"
}
}
1.3 HTML转义
Handlebars默认会转义HTML字符。如果需要输出原始HTML,使用三重大括号 {{{}}}:
⚠️ 安全提示
只有在你信任数据来源时才使用{{{}}},否则可能导致XSS攻击。
{{! 转义HTML(默认) }}
<div>{{content}}</div>
{{ content: "<strong>Hello</strong>" }}
输出: <div><strong>Hello</strong></div>
{{! 不转义HTML }}
<div>{{{content}}}</div>
{{ content: "<strong>Hello</strong>" }}
输出: <div><strong>Hello</strong></div>
2. Built-in Helpers 内置助手
2.1 if 条件判断
{{#if}}助手用于条件渲染,支持{{else}}:
{{#if user}}
<p>欢迎, {{user.name}}!</p>
{{else}}
<p>请先登录</p>
{{/if}}
2.2 unless 反向条件
{{#unless}}是{{#if}}的反向,当条件为false时渲染:
{{#unless is_logged_in}}
<p>请先登录</p>
{{/unless}}
2.3 each 循环遍历
{{#each}}用于遍历数组,提供@index和@key等特殊变量:
示例:遍历数组
<ul>
{{#each items}}
<li>{{@index}}: {{this}}</li>
{{/each}}
</ul>
{{! 数据 }}
{
"items": ["苹果", "香蕉", "橙子"]
}
{{! 输出 }}
<ul>
<li>0: 苹果</li>
<li>1: 香蕉</li>
<li>2: 橙子</li>
</ul>
| 变量 | 说明 |
|---|---|
@index |
当前索引(从0开始) |
@key |
当前对象的键 |
@first |
是否为第一个元素(布尔值) |
@last |
是否为最后一个元素(布尔值) |
2.4 with 上下文切换
{{#with}}用于切换当前上下文,简化嵌套属性的访问:
{{#with user}}
<p>{{name}}</p>
<p>{{email}}</p>
{{/with}}
{{! 等价于 }}
<p>{{user.name}}</p>
<p>{{user.email}}</p>
3. Block Helpers 块助手
💡 块助手特点
块助手可以控制模板的渲染流程,支持options.fn(渲染块内容)和options.inverse(渲染else内容)。
3.1 自定义块助手
{{! JavaScript注册块助手 }}
Handlebars.registerHelper('list', function(items, options) {
var out = "<ul>";
for(var i=0, l=items.length; i<l; i++) {
out += "<li>" + options.fn(items[i]) + "</li>";
}
return out + "</ul>";
});
{{! 模板使用 }}
{{#list items}}
{{title}}: {{price}}
{{/list}}
3.2 带条件的块助手
{{! JavaScript注册 }}
Handlebars.registerHelper('equals', function(a, b, options) {
if (a === b) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
{{! 模板使用 }}
{{#equals status "active"}}
<span class="green">活跃中</span>
{{else}}
<span class="red">已停用</span>
{{/equals}}
4. Custom Helpers 自定义助手
4.1 简单助手函数
{{! JavaScript注册 }}
Handlebars.registerHelper('formatDate', function(date) {
return new Date(date).toLocaleDateString('zh-CN');
});
Handlebars.registerHelper('toUpperCase', function(str) {
return str.toUpperCase();
});
Handlebars.registerHelper('add', function(a, b) {
return a + b;
});
{{! 模板使用 }}
<p>创建时间: {{formatDate created_at}}</p>
<p>{{toUpperCase name}}</p>
<p>总价: {{add price tax}}</p>
4.2 助手参数
助手可以接收多个参数和哈希参数:
{{! JavaScript注册 }}
Handlebars.registerHelper('link', function(text, url, options) {
var attrs = [];
// 处理哈希参数
if (options.hash.class) {
attrs.push('class="' + options.hash.class + '"');
}
if (options.hash.target) {
attrs.push('target="' + options.hash.target + '"');
}
return new Handlebars.SafeString(
'<a href="' + url + '" ' + attrs.join(' ') + '>' + text + '</a>'
);
});
{{! 模板使用 }}
{{link "点击这里" "/about" class="btn" target="_blank"}}
5. Partials 部分模板
Partials允许你重用模板片段,支持动态加载和参数传递。
5.1 注册和使用Partials
{{! JavaScript注册Partial }}
Handlebars.registerPartial('userCard',
'<div class="card">' +
'<h3>{{name}}</h3>' +
'<p>{{email}}</p>' +
'</div>'
);
{{! 模板使用 }}
{{#each users}}
{{> userCard}}
{{/each}}
5.2 动态Partials
{{! 根据变量动态选择Partial }}
{{> (whichPartial) }}
{{! 也可以在each中使用 }}
{{#each items}}
{{> (lookup .. 'itemPartial')}}
{{/each}}
5.3 Partial参数传递
{{! Partial定义 }}
<div class="{{type}}">
<h3>{{title}}</h3>
{{> body}}
</div>
{{! 使用时传递参数 }}
{{> myPartial title="新标题" type="info"}}
这是partial的内容...
{{/myPartial}}
6. Comments 注释
6.1 模板注释
使用{{! --}}添加注释,不会出现在最终输出中:
{{! 这是一个单行注释 }}
{{!-- 这是
一个多行
注释 --}}
<p>这是可见内容</p>
6.2 HTML注释
使用{{! }}会输出HTML注释:
{{! This will appear in HTML output }}
<!-- This will appear in HTML output -->
7. Best Practices 最佳实践
7.1 性能优化
- 预编译模板:在生产环境中预编译模板,避免运行时编译开销
- 使用Partials:将重复的UI组件提取为Partials提高复用性
- 避免深层嵌套:超过3层的嵌套会降低可读性
7.2 安全建议
- 始终转义用户输入:默认使用
{{}}而非{{{}}} - 验证数据来源:不要渲染不受信任的第三方HTML
- 使用CSP:配置Content-Security-Policy头部
7.3 代码组织
- 分离模板和逻辑:业务逻辑放在JavaScript中,模板只负责渲染
- 命名规范:使用有意义的helper和partial名称
- 文档注释:为自定义helpers添加注释说明
🚀 实践建议
使用我们的在线调试器来实时测试你的Handlebars模板, 快速迭代和验证语法正确性。
8. 快速参考表
| 语法 | 说明 | 示例 |
|---|---|---|
{{variable}} |
输出变量(HTML转义) | {{title}} |
{{{variable}}} |
输出变量(不转义) | {{{content}}} |
{{#if}}...{{/if}} |
条件判断 | {{#if active}}...{{/if}} |
{{#each}}...{{/each}} |
循环遍历 | {{#each items}}...{{/each}} |
{{! comment}} |
注释(不输出) | {{! 不会输出 }} |
{{> partial}} |
插入Partial | {{> header}} |