Layui table 原生不支持 columnResize 事件,需手动实现:在 done 中插入绝对定位拖拽条,监听 mouseup 比对 minWidth 变化并触发回调,配合 localStorage 持久化列宽,注意防重排、多表隔离及移动端适配。
layui table 没有 columnResize 事件
layui 官方 table 模块(2.8.x 至 2024 年最新版)**根本不提供列宽调整后的回调事件**,table.on('resize(usertable)') 或类似写法会直接报错或静默失败。你看到的“监听到列宽变化”效果,100% 是自行封装或第三方补丁实现的,不是原生能力。
必须手动监听 mouseup + 判断列宽是否变化
核心逻辑是:在 done 回调中为每列右侧插入透明拖拽条 → 绑定 mousedown 记录初始宽度 → mousemove 动态改 minWidth → mouseup 时比对当前列宽与初始值,有差异才触发自定义回调。
- 拖拽条必须用绝对定位 +
z-index覆盖在表头单元格右侧边缘,宽度建议设为6px,cursor: col-resize - 不能依赖
getBoundingClientRect().width获取列宽——它含 padding/border,应读取td.style.minWidth或从layui-table-col的 data 属性里存取原始值 - 避免在
mousemove中频繁重排,只更新内联style.minWidth,不要调用table.resize()或重绘整表 - 每次
mouseup后需清除document上的mousemove/mouseup监听,否则多个表格共存时会互相干扰
列宽变化后如何持久化并还原
用户拖完就走,下次刷新回到默认宽度,是因为 layui 不保存状态。你要自己存、自己读:
- 变化后立即调用
localStorage.setItem('userTable_colWidths', JSON.stringify(widthMap)),其中widthMap是{'id': 120, 'name': 200, ...}形式 - 在
table.render()前,先读localStorage.getItem('userTable_colWidths'),再把对应字段的width或minWidth写入列配置项 - 注意 key 唯一性:如果同个页面有多个
lay-filter="userTable"表格,必须加路径或 ID 后缀,比如'userTable_' + location.pathname - 不要在
done里直接改obj.config.cols[0][0].width——它只影响当前渲染,下一次table.reload()仍会丢
容易被忽略的兼容性细节
鼠标松开瞬间,列宽可能还没稳定(尤其高 DPI 屏幕或缩放非 100% 时),直接读值容易拿到旧值:
- 在
mouseup后加setTimeout(() => { /* 读宽 */ }, 16),等一帧渲染完成再取 - 不要用
offsetWidth,它可能受父容器隐藏/滚动条影响;优先读computedStyle.minWidth或你预先缓存的 DOM dataset - 移动端无 mouse 事件,
touchstart/touchmove需单独处理,且拖拽条点击热区要放大到 44×44px - 若表格启用了
autoSort: true,排序后列 DOM 会重建,所有拖拽绑定需在每次done里重新初始化


















