Handlebars 模板引擎的 #each 辅助函数非常强大,但它默认只能遍历单个数组。当我们需要同时遍历两个或多个数组,并将它们渲染成表格的多行时(例如第一个数组存放姓名,第二个数组存放年龄),原生语法并不直接支持。下面介绍几种实用的方法来解决这个问题,让你能轻松实现多数组同步遍历并渲染表格。

方法一:预处理合并数组(最推荐)
在将数据传递给模板之前,先将多个数组合并成一个对象数组。这是最直接、最符合 Handlebars 设计理念的方式。你可以在 JavaScript 端使用 Array.prototype.map 或 zip 函数将数据组合好,然后交给模板渲染。
// 原始数据
var names = ['张三', '李四', '王五'];
var ages = [25, 30, 28];
// 合并成对象数组
var people = names.map(function(name, index) {
return {
name: name,
age: ages[index] || '未知' // 防止数组长度不一致
};
});
// 传递给模板
var template = Handlebars.compile(document.getElementById('table-template').innerHTML);
var html = template({ people: people });
document.getElementById('container').innerHTML = html;模板文件(放在 script 标签内):
<script id="table-template" type="text/x-handlebars-template">
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{{#each people}}
<tr>
<td>{{name}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>这种方法清晰简单,符合模板逻辑与数据分离的原则,推荐在实际项目中使用。
方法二:使用自定义 Helper 实现 zip 遍历
如果你不想在 JavaScript 中预处理数据,可以编写一个自定义 Handlebars helper 来模拟 zip 功能,在模板内部同时访问多个数组的元素。
// 注册自定义 helper:zip
Handlebars.registerHelper('zip', function(array1, array2, options) {
var result = [];
var maxLength = Math.max(array1.length, array2.length);
for (var i = 0; i < maxLength; i++) {
result.push({
item1: array1[i],
item2: array2[i],
index: i
});
}
// 使用 #each 循环内部数组
return options.fn(result);
});模板中使用方式:
<script id="table-template" type="text/x-handlebars-template">
<table border="1">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{{#zip names ages}}
<tr>
<td>{{index}}</td>
<td>{{item1}}</td>
<td>{{item2}}</td>
</tr>
{{/zip}}
</tbody>
</table>
</script>调用时传入两个数组 names 和 ages,helper 内部生成一个新数组,每个元素包含 item1、item2 和 index。模板使用 #zip 像 #each 一样循环这个中间数组。
方法三:利用 @index 和原生 #each 索引访问
如果两个数组长度相同,你可以利用 #each 遍历第一个数组,然后通过 @index 作为索引去访问第二个数组的元素。但这种方法只能在手写模板中通过 lookup 辅助函数实现(Handlebars 内置 lookup)。
<script id="table-template" type="text/x-handlebars-template">
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{{#each names}}
<tr>
<td>{{this}}</td>
<td>{{lookup ../ages @index}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>注意:../ages 表示访问父级作用域中的 ages 数组,@index 是当前循环序号(从0开始)。lookup 是 Handlebars 4.0+ 内置的 helper,用于按索引从数组中取值。这种方法不够直观,且难以处理数组长度不一致的情况,仅适合简单场景。
总结对比
下表对比了三种方法的优缺点:
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 预处理合并数组 | 逻辑清晰,模板简单,易于维护 | 需要修改数据源 | 推荐大多数项目 |
| 自定义 helper zip | 模板可复用,无需修改原始数据 | 增加 helper 注册代码,有一定学习成本 | 需要频繁多数组遍历 |
| lookup + @index | 无需额外代码,利用内置功能 | 可读性差,数组长度必须一致,嵌套作用域易出错 | 快速原型或简单表格 |
根据项目实际情况选择合适的方法,大多数情况下预处理合并数组是最安全、最易理解的做法。如果需要更灵活的控制,自定义 helper 也值得一试。希望本文能帮助你解决 Handlebars 同时遍历多个数组的难题,让表格渲染更加得心应手。
Handlebarseach遍历多个数组渲染表格自定义helper修改时间:2026-06-08 15:48:31