layui table 原生不支持多级表头,cols 仅识别单层数组,跨行/跨列需在 done 回调中用 jQuery 手动重写 thead 并保留 data-field 属性,否则排序、导出等功能异常。
layui table 的 cols 配置不支持原生多级表头
layui 2.8.x 及之前版本的 table.render() 中,cols 是二维数组结构,表面看能嵌套,但实际只识别第一层(即最外层数组)为“行”,内层数组会被当成“同一行的列”直接平铺——它压根没有「跨行/跨列」的语义解析能力。所谓“复杂表头”,必须靠手动干预 dom 或 hack 渲染流程实现。
常见错误现象:cols: [[{title: '用户'}, [{field: 'name'}, {field: 'age'}]], [{title: '订单'}, [{field: 'id'}, {field: 'amount'}]]] 这种写法看似分组,结果是表头只渲染出 4 列,且所有 title 全丢,因为 layui 把内层数组当成了无效配置直接跳过。
- 真正能起作用的只有形如
cols: [[{title: '用户信息', colspan: 2}, {title: '订单信息', colspan: 2}], [{field: 'name'}, {field: 'age'}, {field: 'id'}, {field: 'amount'}]]的结构(注意:这是伪代码,layui 原生不认colspan) - 所以你看到的“多级表头”效果,几乎全是靠后续用 jQuery 操作
<th> 的 <code>colspan/rowspan属性硬改出来的 - 如果表格启用了
height或scrollbar,DOM 手动修改后还要主动调用table.resize(),否则表体列宽错位 - 在
table.render()配置里加done: function(res, curr, count) { ... } - 先用
$('table[lay-id="yourTableId"] thead')定位到目标表头容器 - 构造新 HTML 字符串,例如:
<tr> <th colspan="2">用户</th> <th colspan="2">订单</th> </tr> <tr> <th data-field="name">姓名</th> <th data-field="age">年龄</th> <th data-field="id">ID</th> <th data-field="amount">金额</th> </tr> - 执行
$thead.html(newHtml)替换,然后立刻调用table.resize('yourTableId') - 检查方式:右键表头 → “检查元素”,确认每个
<th> 都有 <code>data-field,且值与cols中对应列的field完全相同 - 如果列用了
templet或toolbar,对应<th> 的 <code>data-field应设为''或唯一字符串(如action),并在cols里保持一致 - 不要给合并单元格的
<th> 加 <code>data-field(比如「用户信息」这个总标题),否则 layui 会试图绑定数据导致错乱layui 3.0 尚未发布,别等“官方支持”
社区里常有人问“新版会不会原生支持”,事实是 layui 官方 GitHub 已近 2 年无实质性更新,3.0 处于“传闻中”。所有依赖“未来版本修复”的方案,都会拖慢当前项目进度。
容易被忽略的地方:表头合并后,列宽调整(拖拽)和固定列(
fixed: 'left')会失效或错位。这不是 bug,是 layui 的列宽计算逻辑完全基于单层cols推导的,强行改 DOM 后它无法感知真实结构。如果业务强依赖这两项,建议放弃多级表头,改用卡片式布局或折叠面板分组展示数据。
用 done 回调 + jQuery 重写 <thead><p>这是目前最稳定、兼容性最好的做法:等 layui 渲染完默认表头(单层),再用 <code>done 钩子把 <thead> 整段替换成你手写的 HTML 结构。关键点在于保留原始列的 <code>data-field 和 data-key 属性,否则排序、筛选、导出会失效。
使用场景:需要 2 级及以上表头(比如「部门 → 员工姓名 / 入职时间」、「财务 → 应收 / 实收」);同时要保证 layui 的交互功能不瘫痪。
注意 data-field 必须和原始列定义严格一致
layui 表格内部靠 data-field 绑定数据字段和列行为。如果你在重写的 <th> 里漏了这个属性,或者拼写大小写不一致(比如原始是 <code>userName,你写了 username),点击列排序会报错 Uncaught TypeError: Cannot read property 'sort' of undefined,导出 Excel 时该列数据为空,甚至 checkbox 全选逻辑也会异常。
性能影响:这种 DOM 替换发生在渲染完成后,对首屏时间无影响;但每次调用 table.reload() 后,done 会再次触发,所以重写逻辑必须幂等(比如先清空再写入,或判断是否已存在自定义结构)。


















