layui.table原生不支持拖拽,需手动监听事件模拟;列顺序拖拽需交换cols[0]对象并reload,注意保留page/where/initsort;列宽记忆须存取localstorage且仅覆minwidth;复杂场景推荐soultable.slim.js插件。

拖拽设计必须绕开 layui.table 原生限制
layui.table 本身不提供列拖拽、行拖拽、布局保存等能力——这不是配置漏了,是源码里压根没实现。你看到的“可拖拽”效果,全是靠监听 mouse/touch 事件 + DOM 操作 + table.reload() 模拟出来的。直接在 cols 里加 draggable: true 或调用 table.setColsWidth() 都不会触发任何拖拽行为。
列顺序拖拽:监听 mouseup + reload 时传全量状态
核心逻辑是捕获鼠标松开位置、计算目标列索引、交换 cols[0] 内对象顺序,再用 table.reload() 刷新。但 reload 极易丢状态:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 必须显式传
page(当前页码)、where(筛选条件)、initSort(排序字段和方向),否则分页跳回第 1 页、筛选清空、排序重置 - 如果用了
cache: true,reload 前得先从table.cache['yourTableId']读原始数据,避免重复请求 - 固定列(
fixed: 'left')DOM 独立,只能在同区域内部拖拽;跨 left/right 区域拖动会破坏表头结构 - 移动端慎用手势:iOS/安卓 WebView 中
dragstart基本不可靠,手指一偏就触发页面滚动,drop事件收不到
列宽记忆:存 localStorage + 渲染前注入 minWidth
layui 不保存列宽,拖完就丢。要记住,必须自己存取:
- 监听
mouseup时,用localStorage.setItem('table-' + tableId + '-' + field, String(width)),value 只存纯数字(如150),别带px - 渲染前读缓存:
const saved = localStorage.getItem('table-user-list-username'),然后遍历原始cols[0],找到field === 'username'的列,仅覆盖其minWidth字段(不是width) - 千万别在
done回调里改th.style.width—— 此时 DOM 已渲染,硬塞样式会导致排序图标错位、导出列宽异常 - 多个表格共存时,key 必须含
tableId(来自table.render({ id: 'xxx' })),光用field会串号
真正复杂报表场景下,别硬啃原生事件
当需求包含「列拖拽 + 列宽记忆 + 固定列兼容 + 移动端 fallback + reload 不闪屏」时,自己从零写 mouse 事件链极易翻车。soulTable.slim.js 这类轻量增强插件已封装好这些细节:它把列宽存在 localStorage、列序存在 sessionStorage、拖拽过程禁用文本选中、reload 时自动补全 page/where/initSort、对 fixed 列做 DOM 区域隔离处理。比手写更稳,也省下调试闪烁、错位、跨页失效的时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










