Layui.table 默认不支持表头下方统计行,因其表格结构由内部模板控制且不暴露thead插入点;需在done回调中动态插入tr.table-summary到thead末尾,同步列宽并补充CSS样式,同时确保分页/排序后统计值准确更新。
为什么 layui.table 默认不支持表头下方插一行统计行
layui 的 table.render() 渲染后,表头(<thead>)和数据体(<tbody>)是严格分离的,且整个表格结构由 layui 内部模板控制,不暴露 <thead> 插入点。直接在 thead 里塞两行、或用 cols 配置多级表头,都无法让「统计行」真正位于表头正下方、且与列宽自动对齐——因为统计值需要动态计算,还要响应重绘(如分页、搜索、排序)。
用 done 回调 + 手动插入 <tr class="table-summary">
这是最可控、兼容性最好的做法:等 Layui 渲染完表格 DOM,再在 <thead> 末尾追加一行,并用 JS 计算各列汇总值。关键点在于:
- 必须在
done回调中操作,确保<table>已完整挂载 - 统计行需插入到
<thead>内,而非<tbody>上方,否则 CSS 无法统一作用于表头区域 - 列宽对齐靠监听
table.resize事件 + 同步设置<td>width,否则窗口缩放或列拖拽后会错位
示例片段:
table.render({
elem: '#demo',
url: '/api/list',
cols: [[
{field: 'name', title: '姓名'},
{field: 'score', title: '分数', sort: true},
{field: 'age', title: '年龄'}
]],
done: function(res, curr, count) {
const $table = $(this.elem);
const $thead = $table.find('thead');
let $summary = $thead.find('.table-summary');
<pre class='brush:php;toolbar:false;'>if ($summary.length === 0) {
$summary = $('<tr class="table-summary"></tr>').appendTo($thead);
}
// 清空旧内容,重算
$summary.empty();
const totalScore = res.data.reduce((a, b) => a + (parseFloat(b.score) || 0), 0);
const avgAge = (res.data.reduce((a, b) => a + (parseInt(b.age) || 0), 0) / res.data.length).toFixed(1);
$summary.append('<td>合计</td>');
$summary.append('<td>' + totalScore + '</td>');
$summary.append('<td>' + avgAge + '</td>');
// 同步列宽(关键!)
const $ths = $thead.find('th');
$summary.find('td').each((i, td) => {
if ($ths[i]) {
$(td).width($ths[i].offsetWidth);
}
});} });
必须补的 CSS 样式才能视觉融合
默认插入的 <tr> 没有背景、边框、字体大小,会显得突兀。Layui 表头使用 background-color: #f8f8f8 和 font-weight: bold,统计行应保持一致:
.table-summary td {
background-color: #f8f8f8 !important;
font-weight: bold;
padding: 8px 15px;
text-align: center;
border-bottom: 2px solid #e6e6e6;
}
/* 防止鼠标悬停时高亮覆盖 */
.table-summary:hover {
background-color: #f8f8f8 !important;
}
注意:!important 是必要的,因为 Layui 内联样式优先级高;若用 th 替代 td,需确保 colspan 正确,但更推荐统一用 td 避免渲染异常。
分页/筛选后统计值不更新?记得重触发 table.reload() 的 done
如果用户点击分页、搜索或排序,done 会再次执行,但前提是:你用的是服务端分页(page: true),且接口返回的是当前页数据 —— 这会导致统计值只反映当前页,而非全量。解决方式分两种:
- 服务端返回全量统计字段(推荐):在接口响应里加
summary: {totalScore: 1200, avgAge: 28.4},done中直接取res.summary - 前端全量统计:把所有数据缓存在
table.cache或全局变量,每次done时遍历table.cache["yourTableId"]计算,但要注意内存和性能(万级数据慎用)
别漏掉排序后的缓存刷新:Layui 排序不触发 reload,需监听 table.on('sort(demo)', ...) 并手动重算 $summary 内容。
真正麻烦的不是加一行,而是让它「始终对齐、始终准确、始终不闪」——列宽同步、重绘响应、全量统计来源,这三处漏一个,用户滚动或点一下就会露馅。


















