Layui table 原生不支持列拖拽排序,必须手动实现:为 th 添加 draggable 属性,监听 dragstart 记录索引,drop 时更新 cols 数组并调用 table.reload() 同步顺序。
layui table 原生不支持列拖拽,别在 cols 配置里找 dragCol 参数
直接说结论:table.render() 无论加 fixed、unresize 还是自定义 toolbar,都触发不了列顺序拖拽。官方文档没写,源码里也没 dragcol 或 reordercols 这类配置项——这不是你漏了什么,是它压根没实现。
常见错误现象包括:鼠标 hover 表头没手型、th 上绑 dragstart 事件没响应、用 Chrome DevTools 查看 DOM 发现 th 根本没绑定任何拖拽监听器。
原因很简单:Layui 的 table 模块定位是轻量级数据表格,列顺序属于 UI 层交互逻辑,交由上层业务或插件处理。
必须手动更新 table.config.cols[0] 并调用 table.reload()
关键不是拖动视觉效果,而是拖动结束后能正确更新列定义数组。Layui 表格依赖 cols 数组顺序决定列显示顺序,DOM 结构变化不会自动同步到内部列定义。
仅移动 th 元素会导致:
- 点击列头排序时,实际触发的是原始索引对应的字段,而非当前视觉位置的字段
-
table.cache中每行数据仍是按原始列顺序存储的数组,tr内td与cols错位 - 导出、打印、缓存等行为全部按旧顺序执行
所以必须做三件事:
- 给每个
th添加draggable="true",并在dragstart中记录原始索引(如th.dataset.dragIndex = i) -
drop时读取目标th的dataset.dragIndex,对table.config.cols[0]执行splice移动(注意多级表头需扁平化) - 必须调用
table.reload({ cols: [cols] }),否则所有后续操作仍按原始顺序
固定列(fixed: 'left'/fixed: 'right')不能跨区拖拽
涉及 fixed 列时,只允许在同区域内部拖拽。比如左固定列之间可互换顺序,右固定列之间也可互换,但左固定列不能拖到右固定区,反之亦然——跨区移动会破坏布局,且 table.reload() 后 fixed 渲染逻辑会错乱。
配置时要注意:
- 所有
fixed: 'left'的列应集中写在cols数组前面(彼此相邻),否则渲染顺序和视觉顺序不一致 -
fixed值必须严格为字符串'left'或'right',大小写敏感,不能写成True、1或空字符串 - 左右固定列总宽度不能超过表格总宽,否则触发横向滚动,固定效果失效
用原生 drag API 实现时,drop 事件容易误判目标位置
dragover 在 thead 上默认不触发,必须显式 e.preventDefault();但直接监听 th 的 drop 又容易因鼠标偏移导致目标索引计算错误。
更稳妥的做法是监听 thead 的 drop,再用 e.target.closest('th') 获取目标元素,并结合 $(e.target.closest('th')).index() 算位置。示例关键片段:
$('thead').on('drop', function(e) {
e.preventDefault();
const fromIdx = parseInt(e.target.closest('th').dataset.dragIndex);
const toIdx = $(e.target.closest('th')).index();
if (fromIdx === toIdx) return;
<p>const cols = table.config.cols[0];
const col = cols.splice(fromIdx, 1)[0];
if (fromIdx < toIdx) {
cols.splice(toIdx - 1, 0, col);
} else {
cols.splice(toIdx, 0, col);
}
table.reload({ cols: [cols] });
});注意:如果用了多级表头(即 cols 是二维数组嵌套),上面的 cols[0] 就不够,得先扁平化提取所有叶子节点列再操作——这点最容易被忽略,一拖就乱序。


















