需手动维护跨页选中状态:用 selectedIds 数组记录所有选中行 id,在 checkbox 事件中根据 obj.type 区分单选/全选增删 id,翻页后通过 table.on('render') 延迟调用 form.check() 恢复勾选,并确保 checkbox templet 中 value="{{d.id}}"。
layui table 跨页选中后翻页就丢失,怎么保持状态
默认情况下,layui.table 的复选框选中状态只在当前页生效,翻页后 dom 重绘,之前选中的记录就清空了——这不是 bug,是设计使然:它不自动维护跨页状态,得你自己存、自己读、自己同步。
核心思路是用一个外部数组(比如 selectedIds)手动记录所有被用户点过的行的唯一标识(通常是 id 字段),每次渲染新页时,根据这个数组去比对并设置 checked 状态。
- 必须给每行数据提供稳定、唯一的标识字段(如
id),不能依赖lay-id或索引,否则跨页后无法映射 - 监听
table.on('checkbox')事件,而不是click,否则会漏掉“全选/取消全选”这类操作 - 不要在
done回调里直接改data数组的checked属性——Layui 2.8+ 已不推荐这种写法,容易和内部状态冲突
如何在 checkbox 事件里正确增删 selectedIds
关键不是“点了就加”,而是判断当前行为是勾选还是取消勾选,并据此更新全局 selectedIds 数组。尤其注意“全选”会触发多次单行事件,得靠 event.type === 'all' 区分。
let selectedIds = [];
table.on('checkbox(test)', function(obj){
const id = obj.data.id; // 假设后端返回了 id 字段
if(obj.type === 'all'){
// 全选/取消全选:批量操作 selectedIds
if(obj.checked){
// 把当前页所有 id 加入(注意:仅当前页!)
obj.data.forEach(item => {
if(!selectedIds.includes(item.id)){
selectedIds.push(item.id);
}
});
} else {
// 取消全选:从 selectedIds 中移除当前页所有 id
obj.data.forEach(item => {
const idx = selectedIds.indexOf(item.id);
if(idx > -1) selectedIds.splice(idx, 1);
});
}
} else {
// 单行勾选
if(obj.checked){
if(!selectedIds.includes(id)) selectedIds.push(id);
} else {
const idx = selectedIds.indexOf(id);
if(idx > -1) selectedIds.splice(idx, 1);
}
}
});
翻页后如何恢复 checkbox 选中状态
靠 table.render() 的 done 回调不行,因为此时 DOM 还没生成;得用 table.on('render') 或更稳妥的 setTimeout 延迟一小会儿,等 Layui 把 checkbox 渲染完再遍历打钩。
- 不要用
$('input[type="checkbox"]')直接操作 DOM,Layui 的 checkbox 是封装过的,得用form.render('checkbox')同步状态 - 每次渲染后,遍历当前页所有
tr,取出对应id,查selectedIds,匹配成功就调用form.check()(Layui 2.8+ 推荐)或手动设checked属性再form.render() - 如果用了服务端分页,记得把
selectedIds存到sessionStorage,否则刷新页面就丢了
为什么用 form.check() 比直接改 DOM 更可靠
form.check('checkbox', {value: '123'}) 是 Layui 2.8+ 提供的官方 API,它会主动查找匹配 value 的 checkbox 并打钩,同时触发内部状态更新和样式重绘;而直接 $('input[value="123"]').prop('checked', true) 只改属性,不触发 Layui 的样式同步逻辑,可能导致视觉错位或后续事件异常。
容易忽略的一点:这个 API 要求 checkbox 的 value 属性必须等于你传入的值,所以初始化表格时,得在 cols 中显式写出:{type: 'checkbox', unresize: true, edit: false, templet: ''}
没设 value,form.check() 就找不到目标。










