layui table 原生不支持列宽拖拽,需手动实现:通过插入透明拖拽条、监听 mouseup 捕获结束时机并存入 localStorage,且必须在 cols 初始化阶段注入缓存的 minWidth 值才能生效。
layui table 原生不支持列宽拖拽,必须手动实现
直接调用 table.render() 后鼠标移到列边线没反应、没手型、没宽度变化——这不是你配置错了,是 layui 官方至今(2026 年 7 月)没提供该功能。所有“能拖”的效果都来自自行封装或第三方补丁,不能依赖文档里不存在的 resize 事件或 autoresize: true 参数。
怎么监听拖拽结束并存宽度到 localStorage
layui 不暴露 moveEnd 或 resizeEnd 回调,只能靠 mouseup + DOM 位置判断来捕获拖拽完成时机。核心是在表头 th 右侧插入透明拖拽条(<div class="layui-table-resize"></div>),并在 done 回调中初始化监听逻辑:
- 在
mousedown时记录初始列宽、鼠标 X 坐标、对应列的field和lay-id - 在
mousemove中动态计算新宽度(只改minWidth,避免直接操作th.style.width) - 在
mouseup时写入localStorage,key 推荐格式:table-${tableId}-${field},value 存纯数字(如150,不要带px) - 必须加
event.preventDefault(),否则会触发文字选中或浏览器默认拖拽行为
下次渲染时如何让缓存宽度真正生效
不能等 done 回调再改 DOM 样式,那时表格已渲染完成,硬塞 width 会导致排序图标错位、导出列宽不对。必须在 cols 初始化阶段就注入缓存值:
- 渲染前先读缓存:
const savedWidth = localStorage.getItem('table-user-list-username') - 遍历原始
cols数组,找到field === 'username'的列,仅覆盖其minWidth(例如:{ field: 'username', title: '用户名', minWidth: parseInt(savedWidth) || 120 }) - 只覆盖
minWidth,不动title、sort、templet等其他配置,否则可能破坏筛选或排序逻辑 - 若
savedWidth是null,务必 fallback 到原始默认值(如120)
最容易被忽略导致“存了但没生效”的地方
问题通常不出在拖拽逻辑本身,而在于三个关键点:
-
localStoragekey 没加表格唯一 ID —— 多个表格共用同一页面时,光用username当 key 会串号 - 在
done回调里直接改th.style.width,而不是提前 merge 到cols的minWidth,导致导出和打印仍用原始宽度 - 没处理固定列(
fixed: 'left')场景:左右固定列应使用不同 key 前缀,否则互相覆盖(如加-fixed-left后缀)
拖完关页面,下次进来还是默认宽度——这是预期行为,不是 bug。记住:layui 表格不保存任何列状态,所有持久化都得你自己写,且必须在渲染前完成配置合并。


















