layui table 列拖拽顺序调整原生不支持,需手动监听 mouse 事件并动态重绘表头,通过 table.reload() 传入新顺序 cols 实现,注意保留 page/where 等参数及 fixed 列特殊处理。
layui table 列拖拽顺序调整原生不支持
layui 2.8.x 及之前所有版本的 table.render() 都没有内置列拖拽排序功能,直接调用 table.init() 或设置 cols 数组顺序也不会在 ui 上响应拖拽行为。这不是配置遗漏,而是设计上未实现——官方文档和源码中均无 dragcol、coldraggable 等相关选项。
必须手动监听 mouse 事件 + 动态重绘表头
核心思路是:捕获表头 th 的 mousedown 和 mousemove,计算拖拽位移,临时插入占位 th,松开时调用 table.reload() 并传入新顺序的 cols 数组。注意以下关键点:
- 需在
table.render()的done回调里绑定事件(确保 DOM 已渲染) - 不能直接操作
theadDOM 后“保留状态”,因为 layui 表格每次 reload 都会完全重建整个表格结构 -
cols是二维数组(如[[{field:'id'}, {field:'name'}]]),调整顺序必须替换最内层数组元素位置 - 务必禁用默认文本选中:
document.onselectstart = () => false,否则拖拽时会触发文字高亮干扰
示例:交换两列位置后 reload
假设原始列定义为:
const cols = [[
{field: 'id', title: 'ID'},
{field: 'username', title: '用户名'},
{field: 'email', title: '邮箱'}
]];
用户拖拽“邮箱”列到“ID”列前面,你需要生成新 cols:
const newCols = [[
{field: 'email', title: '邮箱'},
{field: 'id', title: 'ID'},
{field: 'username', title: '用户名'}
]];
然后执行:
table.reload('yourTableId', {
cols: newCols,
// 其他参数如 page、where 若有需一并传入,否则会重置分页/筛选
});
漏传 where 或 page 会导致当前筛选条件丢失或跳回第 1 页。
兼容性与性能隐患
拖拽过程中频繁 reload 会造成明显闪烁,且在数据量大(>1000 行)、列数多(>15 列)时卡顿显著。更稳妥的做法是:
- 仅在
mouseup后 reload 一次,而非实时跟随拖拽 - 用
table.cache['yourTableId']缓存原始数据,避免 reload 时重复请求接口 - 对固定列(
fixed: 'left')单独处理逻辑,它们不在主thead流中,DOM 结构分离 - 移动端无
mouse事件,需额外补充touchstart/touchmove,但 layui 表格本身对移动端支持有限,建议桌面端优先
真正稳定可用的列拖拽,往往要配合 layui.jquery 封装一个轻量级拖拽插件,监听 th 的位移并映射到 cols 索引变更——这个映射关系一旦出错,reload 后列内容和标题就对不上了,是最容易被忽略的断裂点。


















