Handlebars 内置辅助函数:if、each、with
🎯 引言
学会这篇文章,你将掌握 Handlebars 最常用的四个内置辅助函数:if、unless、each 和 with。它们能让模板支持条件判断和列表循环,是实际开发中必不可少的工具。
🧱 if 条件判断
if 用于根据条件决定是否渲染某段内容。
const Handlebars = require('handlebars');
const template = `
{{#if isLogin}}
<p>欢迎回来,{{username}}</p>
{{/if}}
`;
const compiled = Handlebars.compile(template);
const html = compiled({ isLogin: true, username: '小明' });
console.log(html);
输出:
<p>欢迎回来,小明</p>
如果需要 else 分支,可以用 {{else}}:
{{#if isLogin}}
<p>欢迎回来,{{username}}</p>
{{else}}
<p>请先登录</p>
{{/if}}
if 只判断“真值”和“假值”。0、''、null、undefined、[] 都会被视为假值。✨ unless 反向判断
unless 是 if 的反向写法,只有当条件为假时才渲染内容。
{{#unless isLogin}}
<p>你还没有登录</p>
{{/unless}}
它和下面的 if 写法效果一样:
{{#if isLogin}}
{{else}}
<p>你还没有登录</p>
{{/if}}
unless 适合“如果不满足某条件就提示”的场景,代码比 if + else 更简洁。💡 each 循环列表
each 用于遍历数组或对象。
遍历数组
const template = `
<ul>
{{#each list}}
<li>{{this}}</li>
{{/each}}
</ul>
`;
const compiled = Handlebars.compile(template);
const html = compiled({ list: ['HTML', 'CSS', 'JavaScript'] });
console.log(html);
输出:
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
在 each 内部,this 表示当前遍历项。
遍历对象数组
<ul>
{{#each users}}
<li>{{name}} - {{age}}岁</li>
{{/each}}
</ul>
传入:
{ users: [{ name: '小明', age: 18 }, { name: '小红', age: 20 }] }
输出:
<ul>
<li>小明 - 18岁</li>
<li>小红 - 20岁</li>
</ul>
空数组处理
如果数组为空,可以用 {{else}} 显示提示:
<ul>
{{#each users}}
<li>{{name}}</li>
{{else}}
<li>暂无用户</li>
{{/each}}
</ul>
⚖️ each 里的 @index 和 @key
遍历数组时,可以用 @index 获取当前索引:
<ul>
{{#each list}}
<li>{{@index}}. {{this}}</li>
{{/each}}
</ul>
输出:
<ul>
<li>0. HTML</li>
<li>1. CSS</li>
<li>2. JavaScript</li>
</ul>
遍历对象时,用 @key 获取当前键名:
<ul>
{{#each user}}
<li>{{@key}}: {{this}}</li>
{{/each}}
</ul>
🧰 with 切换作用域
with 可以把当前上下文切换成指定对象,避免重复写前缀。
const template = `
{{#with user}}
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
{{/with}}
`;
const compiled = Handlebars.compile(template);
const html = compiled({
user: { name: '小明', age: 18 }
});
console.log(html);
输出:
<p>姓名:小明</p>
<p>年龄:18</p>
进入 {{#with user}} 后,里面的 {{name}} 和 {{age}} 就直接从 user 对象里取了。
with 后面的值为假值(比如 null、undefined),内部内容不会渲染。🧾 小节总结
if用于条件渲染,支持else分支。unless是if的反向写法,条件为假时渲染。each用于遍历数组或对象,支持else处理空数据。@index和@key分别用于获取数组索引和对象键名。with可以切换上下文,减少重复前缀。
❓ 知识问答
Q1:Handlebars 的 if 能写复杂表达式吗?
A:不能。Handlebars 主张“模板里不写复杂逻辑”,if 里只能写单个变量或简单值,不能写 a > b、a && b 这类表达式。需要复杂判断时,可以在传入数据前计算好,或自定义 Helper。
Q2:each 里可以用 {{name}} 直接访问对象属性吗?
A:可以。遍历对象数组时,当前项就是上下文,{{name}} 会读取当前项的 name 属性。
Q3:with 和直接写 user.name 有什么区别?
A:功能一样,with 只是让代码更简洁。当某个对象属性很多时,用 with 可以减少重复前缀。
Q4:空数组在 each 里会报错吗?
A:不会。空数组会跳过渲染,可以用 {{else}} 给出友好提示。
🧪 小练习
给定以下数据,请编写 Handlebars 模板:
const data = {
isVip: true,
products: [
{ name: '苹果', price: 5 },
{ name: '香蕉', price: 3 }
]
};
// 请在这里编写模板
// 要求:
// 1. 如果 isVip 为 true,显示“VIP 专享”
// 2. 用 each 渲染 products 列表,显示名称和价格
🎉 恭喜你掌握了 Handlebars 的内置辅助函数!下一篇我们会学习 Partials,让模板可以像组件一样复用。
