Layui table 原生不支持列拖拽排序,需手动实现或使用第三方插件 layui-table-colmove;拖拽仅影响前端显示顺序,导出/打印仍按原始 cols,须同步 cols 配置或持久化状态。
layui table 列拖拽排序原生不支持
layui 的 table 模块本身没有提供列顺序拖拽(即拖动表头调整列显示顺序)的 api 或配置项。这是个常见误解——很多人以为开启 cols 配置或设置 fixed 就能触发列拖拽,实际不行。
官方文档里找不到 dragCol、reorderCols 这类参数,所有“列拖拽”效果都需手动实现。
用 mouse 事件 + DOM 重排模拟拖拽行为
核心思路是监听表头 th 的 mousedown、mousemove、mouseup,动态移动当前列并更新 cols 数组结构,最后调用 table.reload() 重绘表格。
关键注意点:
- 必须在
table.render()完成后操作 DOM,否则th元素尚未生成 - 拖拽过程中要临时隐藏被拖列(避免视觉错乱),用伪元素或绝对定位模拟“影子”
- 列宽、
field、templet等配置必须完整保留在cols数组中,不能只交换title - 涉及固定列(
fixed: 'left'或'right')时,只允许在同区域内部拖拽,跨区移动会破坏布局
示例片段(绑定到渲染后的表格容器):
const $table = $('#demo'); // 表格容器
const cols = [[ /* 原始 cols 配置 */ ]];
let draggingIndex = -1;
let targetIndex = -1;
<p>$table.on('mousedown', 'thead th', function(e) {
if (e.button !== 0) return; // 只响应左键
const $th = $(this);
draggingIndex = $th.index();
$th.addClass('layui-table-dragging');</p><p>$(document).on('mousemove.layuiColDrag', handleMouseMove);
$(document).on('mouseup.layuiColDrag', handleMouseUp);
});</p><p>function handleMouseMove(e) {
const $ths = $table.find('thead th');
const offset = e.pageX - $ths.eq(draggingIndex).offset().left;
$ths.each((i, th) => {
if (i === draggingIndex) return;
const left = $(th).offset().left;
if (offset > 0 && e.pageX > left + $(th).width() / 2) {
targetIndex = i;
} else if (offset < 0 && e.pageX < left + $(th).width() / 2) {
targetIndex = i;
}
});
}</p><p>function handleMouseUp() {
if (targetIndex < 0 || draggingIndex < 0 || draggingIndex === targetIndex) {
$(document).off('.layuiColDrag');
return;
}</p><p>// 在 cols[0] 中调整列顺序(假设只有一级表头)
const colArr = cols[0];
const draggedCol = colArr.splice(draggingIndex, 1)[0];</p><p>if (targetIndex > draggingIndex) {
colArr.splice(targetIndex - 1, 0, draggedCol);
} else {
colArr.splice(targetIndex, 0, draggedCol);
}</p><p>table.reload('demo', { cols: cols });
$(document).off('.layuiColDrag');
}
第三方插件方案:layui-table-colmove
社区有轻量封装插件 layui-table-colmove,它基于上述原理做了兼容处理,支持多级表头、固定列、响应式宽度保留等。但要注意:
- 必须在
layui.use(['table', 'colmove'], ...)中显式引入,不能直接 script 标签加载 - 它会劫持
table.init和table.render,若项目已重写 table 模块可能冲突 - 不支持 layui 3.0+(目前最新稳定版仍是 2.9.25),升级前务必验证
启用方式简单:
table.render({
elem: '#demo',
url: '/api/list',
cols: [[
{field: 'id', title: 'ID', width: 80},
{field: 'username', title: '用户名'}
]],
colmove: true // 插件识别的关键配置
});
列拖拽后导出/打印样式容易错位
拖拽只改变前端 cols 顺序,不影响服务端返回的数据结构。但如果用了 export 模块导出 Excel,或调用 print 打印,列顺序仍按原始 cols 渲染,导致前后不一致。
解决方法只有两个:
- 导出前手动同步当前
cols到导出配置(比如传给exportFile的cols参数) - 把列顺序存在 localStorage,每次 render 前读取并重组
cols,让初始状态就匹配用户上次操作
这个细节常被忽略,直到用户反馈“我明明拖了列,导出还是老顺序”。

















