如何使用Mustache.js按指定间隔生成表格行?无需修改数据源的优化方案
解决Mustache.js 1.0.0生成2列表格的行标签问题
首先明确:Mustache.js是「无逻辑」模板引擎,1.0.0版本本身不支持直接在模板里通过索引奇偶判断插入<tr>/</tr>标签,但我们可以通过两种优雅的方式实现需求,完全不需要修改原始数据源的结构:
方法1:预处理数据源(推荐,更符合Mustache设计理念)
核心思路是把原始数据转换成「按行分组」的结构(每2个元素为一行),这样模板就能直接循环行和单元格,自然生成正确的表格结构。
步骤1:编写数据分组函数
这个函数会把你的原始二维数组,转换成每行包含2个元素的三维数组:
function groupItemsIntoRows(rawData, itemsPerRow = 2) { return rawData.map(sheetData => { const rows = []; // 遍历每个sheet的元素,每2个一组生成行 for (let i = 0; i < sheetData.length; i += itemsPerRow) { rows.push(sheetData.slice(i, i + itemsPerRow)); } return rows; }); } // 用你的目标数据源调用函数 const desiredData = [ [{name:"one"},{name:"two"},{name:"three"},{name:"four"}], [{name:"five"}] ]; const processedData = groupItemsIntoRows(desiredData);
步骤2:修改模板适配分组后的数据
模板变得非常简洁,直接循环行和单元格即可:
<script id="template" type="text/template"> {{#.}} <section class="sheet padding-10mm php"> <table class="pagedTable"> {{#.}} <!-- 循环每一行 --> <tr> {{#.}} <!-- 循环行内的每个单元格 --> <td>{{name}}</td> {{/.}} </tr> {{/.}} </table> </section> {{/.}} </script>
步骤3:渲染模板
const template = $('#template').html(); $('body.letter').append(Mustache.to_html(template, processedData));
这种方法的优势是完全遵循Mustache「数据驱动渲染」的设计,逻辑全部放在数据预处理阶段,模板保持干净无逻辑。
方法2:使用Mustache Lambda函数(适合不想改动数据结构的场景)
Mustache支持Lambda函数,可以在模板中嵌入逻辑判断。我们需要给每个元素添加索引,再通过Lambda判断奇偶来插入行标签,同时处理最后一个元素是奇数的边界情况。
步骤1:给数据添加索引和边界标记
function prepareDataWithIndices(rawData) { return rawData.map(sheetData => { const indexedItems = sheetData.map((item, idx) => ({ ...item, index: idx + 1 // 索引从1开始,方便判断奇偶 })); return { items: indexedItems, needClosingTr: indexedItems.length % 2 === 1 // 判断最后一行是否需要补</tr> }; }); } const templateData = { sheets: prepareDataWithIndices(desiredData), // 定义Lambda函数:判断当前元素索引是否为奇数 isOdd: function() { return (text, render) => { return this.index % 2 === 1 ? render(text) : ''; }; }, // 定义Lambda函数:判断当前元素索引是否为偶数 isEven: function() { return (text, render) => { return this.index % 2 === 0 ? render(text) : ''; }; } };
步骤2:修改模板使用Lambda
<script id="template" type="text/template"> {{#sheets}} <section class="sheet padding-10mm php"> <table class="pagedTable"> {{#items}} {{#isOdd}}<tr>{{/isOdd}} <td>{{name}}</td> {{#isEven}}</tr>{{/isEven}} {{/items}} <!-- 处理最后一个元素是奇数的情况,补闭合标签 --> {{#needClosingTr}}</tr>{{/needClosingTr}} </table> </section> {{/sheets}} </script>
步骤3:渲染模板
const template = $('#template').html(); $('body.letter').append(Mustache.to_html(template, templateData));
总结
- 推荐使用方法1,因为它更简单,也符合Mustache作为无逻辑模板的定位,避免在模板中嵌入复杂逻辑。
- 方法2适合无法修改数据结构的场景,但需要额外处理边界情况,代码复杂度稍高。
内容的提问来源于stack exchange,提问作者J nui
相关产品推荐
相关产品推荐

