根本原因是reload清空DOM状态但未恢复data中的勾选逻辑,须在done回调中基于主键(如id)重置LAY_CHECKED及checkbox样式和全选框状态。
表头排序触发 reload 后选中状态丢失的根本原因
layui 的 table.sort() 默认会触发一次 reload,而 reload 会清空当前表格的 dom 状态(包括 input[type="checkbox"] 的 checked 属性和 layui-form-checked 类),但不会自动恢复 data 中记录的勾选逻辑。即使你用 setrowchecked 或手动改 lay_checked,只要 reload 一执行,这些状态就断开了。
必须在 done 回调里重置每行的 LAY_CHECKED 和 UI 样式
关键不是“阻止 reload”,而是 reload 完成后,在 done 回调里立刻同步已选数据到新渲染的行。你需要:
- 用一个全局数组(如
temp_all_list)持久化所有已选中的唯一标识(推荐用主键id字段) - 在
done中遍历res.data,对每个对象检查其id是否在temp_all_list中存在 - 若存在,手动设置
o["LAY_CHECKED"] = true,并用 jQuery 找到对应tr[data-index]行,补上checked属性和layui-form-checked类 - 别漏掉全选框状态:调用
table.checkStatus('your_id')判断是否全选,再手动同步表头 checkbox 的 UI
示例片段(注意 data-index 是 layui 内部索引,不是原始数据 index):
done: function(res, currPage, count) {
temp_table_list = res.data;
temp_table_list.forEach(function(o) {
if (temp_all_list.some(item => item.id === o.id)) {
o["LAY_CHECKED"] = true;
var index = o["LAY_TABLE_INDEX"];
$('.layui-table tr[data-index="' + index + '"] input[type="checkbox"]')
.prop('checked', true)
.next().addClass('layui-form-checked');
}
});
// 同步全选框
var status = table.checkStatus('user_table');
var allChecked = status.data.length > 0 && status.data.length === temp_table_list.length &&
temp_table_list.every(o => temp_all_list.some(i => i.id === o.id));
$('.layui-table th[data-field="0"] input[type="checkbox"]')
.prop('checked', allChecked)
.next().toggleClass('layui-form-checked', allChecked);
}
监听排序事件时避免重复绑定和状态污染
如果你在 table.on('sort(your_filter)') 里直接操作 temp_all_list,容易因多次点击同一列、或 shift/ctrl 组合排序导致逻辑错乱。更稳妥的做法是:
- 只在
sort事件里收集排序参数(field和type),不修改选中状态 - 把真正的 reload 和状态恢复逻辑全部收口到
done回调 - 如果用了自定义多列排序(如按住 shift 添加字段),确保后端返回的数据顺序与前端期望一致;否则
res.data顺序错,data-index就对不上,UI 恢复必然失败
注意 LAY_TABLE_INDEX 在 reload 后会重排,不能依赖原始顺序
res.data 是当前页数据,o["LAY_TABLE_INDEX"] 是 layui 渲染时分配的行序号(从 0 开始)。每次 reload 后这个值都会重置,所以你不能用它做跨页或跨排序的持久索引。唯一可靠的锚点是业务主键(如 id、eno),所有状态比对和查找都必须基于它。
如果你的后端没返回稳定主键,或者用了前端分页(page: false),那得额外缓存原始数据索引映射表——这种场景下,保持勾选的复杂度会陡增,建议优先推动后端补主键字段。











