合计项必须在done回调中手动计算并插入tbody底部。需清空旧合计行,遍历res.data求和,创建tr插入指定tbody,注意colspan匹配列数、空数据时仍显示“0”。
合计项加在哪儿?先确认表格渲染完成时机
直接在 cols 配置里加一列放合计,layui 不会自动计算——它只负责渲染数据行。合计必须手动算、手动塞,且得等表格重绘完毕再操作,否则 dom 还没生成就去查元素,必然失败。
-
done回调是唯一可靠时机:它在表格数据全部渲染完、分页栏也挂好之后触发 - 别用
success:它只在 Ajax 返回成功时触发,此时 DOM 还未渲染,layui.table.cache也未必已写入 - 如果启用了
height(固定高度),合计行要插在.layui-table-box .layui-table-body table的tbody底部,否则会被滚动截断
怎么把合计行塞进表格 body?用原生 DOM 操作最稳
Layui 表格的 body 是动态生成的,不建议用 jQuery 的 append 或 after,容易被后续重绘覆盖。应直接操作 tbody 原生节点,并确保插入位置在最后一行之后。
- 先用
layui.table.cache["id"]拿到当前页所有数据(注意:不是全部数据,只是当前页) - 遍历求和,比如对
price字段累加:data.reduce((sum, item) => sum + (parseFloat(item.price) || 0), 0) - 定位目标
tbody:document.querySelector(".layui-table[lay-id='yourId'] tbody") - 创建
tr,设 class 为layui-table-total(可选,方便 CSS 区分),然后appendChild到tbody
done: function(res, curr, count) {
const tbody = document.querySelector(".layui-table[lay-id='demo'] tbody");
if (!tbody) return;
// 清掉旧合计行(避免翻页重复添加)
const oldTotal = tbody.querySelector(".layui-table-total");
if (oldTotal) oldTotal.remove();
// 计算合计
const total = res.data.reduce((s, d) => s + (parseFloat(d.amount) || 0), 0);
// 插入新合计行
const tr = document.createElement("tr");
tr.className = "layui-table-total";
tr.innerHTML = `<td colspan="3">合计</td><td>${total.toFixed(2)}</td>`;
tbody.appendChild(tr);
}
合计列对不齐?检查 colspan 和列宽是否匹配
合计行错位,90% 是因为 colspan 值和实际列数不一致,或者表格开启了 fixed(固定列),导致 body 分成了多个 tbody 区域。
- 用
layui.table.config["yourId"].cols[0].length获取真实列数(注意是二维数组第一层的长度) - 如果某列设置了
fixed: 'left'或fixed: 'right',合计行需分别插入左/中/右三个tbody,否则只在中间区域显示 - 避免用百分比或
minWidth设置列宽,合计单元格宽度由内容撑开更可控 - 给合计行加样式:
.layui-table-total td { background-color: #f8f8f8; font-weight: bold; }
翻页后合计消失?必须每次 done 都重算重插
很多人只在初始化时算一次合计,结果翻页、搜索、重载后合计就没了——因为 done 是每次数据变更后必走的钩子,漏掉就等于放弃更新。
- 不要把合计逻辑写在
init外部,必须包在done里 - 如果需要全量合计(不是当前页),得自己发额外请求或在后端返回
totalAmount字段,前端直接取用 - 注意
res.data是当前页数据,res.count是总条数,二者别混用
最易忽略的一点:当表格为空(res.data.length === 0)时,仍要插入合计行并显示“0”,否则 UI 断层。这个边界情况几乎没人处理,但用户一眼就能察觉。











