Layui.table 不支持 cols 中的 rowspan/colspan,需在 done 回调中用 layui.$ 手动合并:遍历 tr,按字段值连续相同统计行数,首行设 rowspan,后续同行对应 td 设 display:none。
layui.table.render 里用 cols 配置 rowspan 和 colspan 不生效?
因为 layui 的表格(layui.table)本身不支持原生的 html rowspan/colspan 渲染,所有列配置里的 rowspan 或 colspan 字段会被忽略——这不是你写错了,是框架压根没实现这个能力。
真正能合并单元格的方式只有一种:靠 done 回调 + 原生 DOM 操作手动合并。Layui 渲染完表格后,它生成的是标准的 <table> 结构,这时你才有机会用 JS 控制 td 的属性。
- 必须等
done执行完毕再操作 DOM,否则tbody还没渲染出来 - 不要在
init阶段或parseData里尝试改配置项,无效 - 合并逻辑要自己判断哪几行/列数据相同,Layui 不提供自动分组合并
怎么在 done 里安全合并行(比如按某字段相同就纵向合并)
核心思路是:遍历 tbody tr,统计连续相同值的行数,然后给首行设 rowspan,其余行用 display: none 隐藏对应单元格(不能直接删,会破坏 Layui 内部索引)。
注意:只对目标列操作,其他列保持不变;且必须用 layui.$(不是 jQuery),避免冲突。
- 用
layui.$(elem).find('tbody tr')获取真实渲染后的行节点 - 从第 0 行开始循环,用
data-index属性定位原始数据索引(Layui 自动加的) - 合并前先保存原始
td内容,避免被隐藏后取不到值 - 设
rowspan后,记得把后续行对应td的style.display = 'none'
done: function(res, curr, count) {
const $ = layui.$;
const tbody = $(this.elem).find('tbody');
const rows = tbody.find('tr');
let i = 0;
while (i < rows.length) {
const current = $(rows[i]);
const currentValue = current.data('index') && res.data[current.data('index')].category;
let rowspan = 1;
// 向下找相同 category 的连续行
for (let j = i + 1; j < rows.length; j++) {
const nextVal = $(rows[j]).data('index') && res.data[$(rows[j]).data('index')].category;
if (nextVal === currentValue) rowspan++;
else break;
}
if (rowspan > 1) {
const targetTd = current.find('td').eq(1); // 第二列(索引1)
targetTd.attr('rowspan', rowspan);
for (let k = 1; k < rowspan; k++) {
if (i + k < rows.length) {
$(rows[i + k]).find('td').eq(1).css('display', 'none');
}
}
}
i += rowspan;
}
}
列合并(横向合并)为什么更难、也更少用
列合并本质是让多个 td 横向融合成一个,但 Layui 表格每行 td 数量严格对应 cols 配置长度,强行删或合会导致样式错位、鼠标悬停异常、甚至排序/筛选功能失效。
真有横向聚合需求(比如表头「销售额」下分「线上」「线下」两列),应该走表头分组,而不是合并单元格:
- 在
cols里用嵌套数组定义二级表头:[[{title:'销售额', colspan:2}, {title:'订单数', colspan:1}], [{field:'online', title:'线上'}, {field:'offline', title:'线下'}, {field:'count', title:'总数'}]] - 这种写法由 Layui 原生支持,不会出兼容问题
- 不要试图在
done里给th加colspan,容易和内部列宽计算冲突
合并后排序、搜索、分页还正常吗
只要没动 res.data 原始结构,只是操作了渲染后的 DOM,排序、搜索、分页都照常工作——因为这些功能全依赖数据层,和界面是否合并无关。
但要注意两个实际影响:
- 导出 Excel(如果用了
table.exportFile)时,合并效果不会保留,导出的是原始数据结构 - 响应式模式下(
skin: 'line'或小屏),display: none的单元格可能造成高度塌陷,建议加vertical-align: middle兜底
最麻烦的其实是后续维护:别人接手代码时,很难一眼看出哪里做了 DOM 合并,尤其是没有注释 done 里的操作目的。留个 // 合并 category 列:rowspan 逻辑 很有必要。


















