必须传 table 实例而非字符串调用 checkAll 才能确保 DOM 同步;服务端分页下需区分视觉全选(手动同步各页勾选状态)与业务全选(用 Set 管理全部 ID);toolbar 计数需监听 checkbox 事件并结合 isAll 和 data 动态更新。
点击 toolbar 按钮触发全选,必须用 table.checkAll 并传入正确参数
直接调用 table.checkall('demo') 往往没反应,不是 api 失效,而是传参方式错了。layui 的 table.checkall 有两个行为分支:传字符串(如 'demo')时,它会通过 lay-id 查找表格实例并只操作当前页;传 table 实例(即 render() 返回的 inst)时,才能确保作用于目标表格且 dom 状态同步。
实操建议:
- 在
table.render()中保存返回值:var inst = table.render({ ... }) - toolbar 按钮绑定 click 事件后,调用
inst.checkAll()(注意不是字符串) - 确保表格启用了
checkbox: true,且每行数据有有效id字段(不能是null或undefined) - 如果表格是服务端分页(
page: true),checkAll()仍只影响当前页——这是设计限制,不是 bug
服务端分页下“视觉全选”和“业务全选”必须分开处理
用户点 toolbar 全选按钮,UI 上希望所有页都打钩,但浏览器本地根本不知道第 2 页、第 3 页有哪些数据。这时候强行让 DOM 全勾上,table.checkStatus() 还是拿不到跨页数据——因为那些行还没渲染。
常见错误现象:按钮点了,表头 checkbox 勾上了,但翻页后新行没勾,checkStatus 的 data 仍是空的。
应对方式取决于你的业务需求:
- 只要 UI 视觉一致(比如翻页后也自动勾):监听
table.on('page(test)'),每次翻页后遍历table.cache['test'],把已选 ID 集合里的匹配项手动设为勾选状态(用$(tr).find('input[type="checkbox"]').prop('checked', true)+ 补样式) - 要真正“业务全选”(比如提交时发全部 ID 给后端):不依赖 DOM,改用全局
Set记录所有已选 ID;toolbar 全选时清空 Set 再填入全部table.cache['test'].map(d => d.id);提交前把 Set 转数组传出去 - 如果数据量极大(10 万+),别在翻页回调里反复遍历
table.cache,会卡顿;优先走后端批量接口,前端只传个 “全选标记”
为什么用 setTimeout(0) 在 done 里调用 checkAll 还是失败
很多人照着文档在 done 回调末尾加 setTimeout(() => inst.checkAll(), 0),结果还是没反应。根本原因不是时机问题,而是实例没拿到或状态未就绪。
关键检查点:
-
inst必须是当前表格的 render 返回值,不能是其他表格的、也不能是重复 render 覆盖后的旧引用 -
done回调里的res是当前页数据,不代表整个table.cache已加载完成;如果表格是服务端分页,table.cache只有首屏数据 - 检查控制台是否有
Uncaught TypeError: Cannot read properties of undefined—— 大概率是inst为undefined或被覆盖 - 确认
lay-id属性存在且唯一:<table id="demo" lay-id="demo">;<code>table.checkAll字符串模式严重依赖它toolbar 按钮模板里怎么显示“已选 X 行”并实时更新
Layui 不提供响应式绑定,
toolbar区域的文本必须手动更新。不能只靠table.checkStatus().data.length,那只是当前页数。正确做法:
- 给 toolbar 容器加唯一 ID,比如
<div id="toolbar-count">已选 0 行</div> - 在
table.render()的done回调里,绑定 checkbox 事件:table.on('checkbox(test)', function(obj){ updateCount(); }) -
updateCount函数里判断:if (obj.isAll) { count = obj.count } else { count = obj.data.length },再更新 DOM - 特别注意边界:取消全选后
isAll变false,但data可能为空,此时应显示 0,而不是跳过
最常漏的是把
isAll当作“已选总数”,其实它只是个开关标志;真实数量要么来自后端 total,要么靠前端自己维护集合。这两个点一错,“已选 X 行”就永远对不上。 - 给 toolbar 容器加唯一 ID,比如











