Layui表格排序后选中状态丢失是因为sort事件重绘tbody时不保留table.cache中的checked标记;需在done回调中遍历table.cache,根据持久化的ID集合手动恢复checked状态并调用table.checkStatus()更新UI。
为什么排序后选中状态会丢失
layui 表格默认在 sort 事件触发时会重新渲染 tbody,但不会保留 table.cache 中的 checked 状态标记——它只在初始化或 reload 时读取原始数据,排序过程不触发状态同步。结果就是:你勾选了第 3 行,一点击表头排序,那行 dom 虽然还在,但 checked: true 标记被清空,table.checkstatus() 返回空数组。
用 done 回调 + table.cache 恢复选中状态
必须在每次排序完成、表格重绘后,手动把之前记住的 ID 映射回新顺序下的行,并打上 checked: true 标记。
- 在
table.render()配置里定义一个全局变量(如window.checkedIds = new Set())来持久化已选中的唯一标识(推荐用业务字段如id) - 监听
table.on('sort(filter)', ...),在里面调用table.checkStatus()获取当前页已选 ID,合并进window.checkedIds - 在
done: function(res, curr, count) { ... }中遍历table.cache[tableId],对每条数据判断item.id是否在window.checkedIds里,是则设item.checked = true - 最后必须显式调用
table.checkStatus(tableId)触发 UI 更新(仅改 cache 不够)
rowClickToCheck 开启时的额外注意点
如果你用了 rowClickToCheck: true,排序后点击某行会“看起来”没反应——因为 layui 内部仍按旧索引找行,而 DOM 顺序已变。此时不能依赖 obj.setRowChecked() 的默认行为。
- 禁用
rowClickToCheck,改用table.on('row(filter)', ...)手动处理 - 在回调里先通过
obj.data.id查table.cache得到真实 index,再调用table.setRowChecked(tableId, { index, checked: !obj.data.checked }) - 避免用
obj.data.LAY_TABLE_INDEX—— 它是渲染序号,排序后失效
服务端分页场景下别漏掉 reload 同步
服务端分页时,排序请求会带 field 和 order 参数返回新数据,table.cache 会被整个替换。此时你存的 window.checkedIds 还有效,但 done 里必须重新遍历新 table.cache 并打标。
- 确保
reload时不重置window.checkedIds - 如果用户在第 2 页选中了某些行,然后排序,接口返回的是第 1 页数据 —— 此时
window.checkedIds里那些不在当前页的 ID 就不该打标,否则视觉错乱 - 更稳妥的做法:排序前先
table.checkStatus()拿当前页所有已选项,和服务端约定加个keepCheckedIds字段透传过去,由后端决定是否返回全量匹配数据
done 里重打 checked 标记,以及误用 obj.data.LAY_TABLE_INDEX 做索引定位——这两个点一错,选中状态就彻底不可控。











