layui 2.8+ 已废弃 table 的 group 参数,需通过 done 回调手动合并单元格实现分组;必须保证数据按分组字段排序、每行有唯一 id,并在 done 中用 rowspan + 隐藏重复单元格完成视觉分组。
layui table 的 group 参数不起作用?先确认是否用了新版 api
layui 2.8+ 的 table.render() 已废弃旧版的 group 配置,直接写 group: true 不会生效。真要分组,得靠 done 回调 + 手动合并单元格,或者换用 tree 模式模拟分组效果。
常见错误现象:group: 'category' 配置后表格照常平铺,列头没变化,控制台也没报错——这说明你正踩在旧文档坑里。
- 新版 Layui(≥2.8)只支持通过
cols中的rowspan/colspan手动控制合并,没有内置列级自动分组 - 如果数据已按分组字段排序(如
category相同值连续),可在done回调里遍历data计算重复行数,再调用table.cache和table.setRowElem注入rowspan - 不推荐强行 patch
table.js加 group 功能——后续升级会覆盖,且破坏渲染生命周期
用 done 回调实现「同一列值相同时合并首列」的实操步骤
这是目前最稳定、兼容性最好的做法,适用于需要视觉分组但不改数据结构的场景(比如后台日志按日期归类、商品列表按品牌折叠)。
关键点:必须保证原始数据中分组字段(如 brand)已排序,否则合并逻辑会出错。
- 在
table.render()配置里写done: function(res, curr, count) { ... } - 用
res.data遍历,对比当前项与上一项的brand值是否相同,记录连续重复次数 - 调用
table.setRowElem(res.data[i].id, { rowspan: n })给首行设rowspan,其余重复行用css('display', 'none')隐藏内容单元格 - 注意:
id字段必须存在且唯一,否则setRowElem失效;若没传id,得用res.data[i].LAY_TABLE_INDEX替代
done: function(res) {
let lastBrand = '';
let rowspan = 1;
res.data.forEach((item, i) => {
if (item.brand === lastBrand) {
rowspan++;
// 隐藏后续行的 brand 单元格
$(`tr[data-index="${i}"] td[data-field="brand"]`).css('display', 'none');
} else {
if (rowspan > 1) {
$(`tr[data-index="${i - rowspan}"] td[data-field="brand"]`).attr('rowspan', rowspan);
}
lastBrand = item.brand;
rowspan = 1;
}
});
// 最后一组别漏掉
if (rowspan > 1) {
$(`tr[data-index="${res.data.length - rowspan}"] td[data-field="brand"]`).attr('rowspan', rowspan);
}
}
为什么不用 tree 模式?它和分组不是一回事
tree 模式本质是嵌套结构渲染,要求数据带 children 字段,适合菜单、组织架构这类父子明确的关系。而「按某一列自动分组」是扁平数据的视觉聚合,两者语义不同,硬套会导致数据冗余或交互错乱。
- 如果你强行把
brand: 'Apple'的所有行塞进一个children数组,那导出 Excel、排序、搜索都会异常——因为 Layui 的tree默认禁用这些功能 -
tree的展开/折叠图标是固定加在第一列的,无法挪到任意列,也不支持多级分组(比如先按category再按brand) - 真实项目中,分组列往往还要支持点击筛选、tooltip 提示总数,这些都得额外写事件绑定,
tree模式反而增加维护成本
容易被忽略的 CSS 和性能细节
手动合并单元格后,表格样式很容易错位,特别是用了 fixed: true 或自定义 cellMinWidth 的时候。
- 隐藏单元格不能只靠
display: none,得补一句border: none,否则边框残留导致列宽计算异常 - 大量数据(>500 行)下,
done回调里的 DOM 操作会卡顿,建议用documentFragment批量更新,或改用虚拟滚动 + 分页分组 - 移动端 Safari 对
rowspan渲染有 bug,偶尔会撑开空白行——加个td[rowspan] { vertical-align: middle; }能缓解 - 如果分组列需要支持排序,记得在排序回调里重跑一遍合并逻辑,否则
rowspan还留在老位置
分组这事,表面是 UI 效果,实际卡点全在数据顺序、DOM 控制粒度和边界 case 处理上。没排序的数据、没 id 的行、没清空的旧 rowspan——这三个点,90% 的问题都出在这儿。











