必须用列内templet模板绑定单行数据并动态禁用按钮,顶部toolbar无法获取行上下文;模板中根据d.status控制disabled属性,事件回调中须二次校验状态,且模板script标签需在table.render前静态存在dom中。
用 templet 渲染按钮并内联判断字段值
直接在列配置里写 templet 函数或模板脚本,根据当前行数据(d)的字段值决定是否加 disabled 属性。layui 的工具栏按钮不自带行上下文,所以必须放弃顶部 toolbar,改用列内模板——这是唯一能稳定绑定单行数据的方式。
常见错误现象:写了 disabled 但点击仍生效 → 实际是没配 lay-event,或禁用后没在事件回调里二次校验。
- 列定义中删掉
{fixed: 'right', toolbar: '#barDemo'}这类全局 toolbar 引用 - 换成普通列:
{field: 'status', title: '操作', templet: '#actionTpl'} - 页面中定义
<script type="text/html" id="actionTpl"></script>模板,里面写:{{# if(d.status === 'draft'){ }} <button class="layui-btn layui-btn-danger layui-btn-xs" disabled>删除</button> {{# } else { }} <button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</button> {{# } }} -
name或lay-event不要加在disabled按钮上,Layui 会忽略它;只对可交互按钮设lay-event
事件回调里必须二次校验字段状态
用户可能手动删掉 DOM 上的 disabled,或用键盘触发 lay-event,所以仅靠模板禁用只是第一道防线。真正执行操作前,得在 table.on('tool(test)') 回调里再读一次 obj.data.status。
性能影响不大,但漏掉这步会导致业务逻辑被绕过——比如草稿状态的行被误删。
- 所有
lay-event处理函数开头都加判断:if(obj.data.status === 'draft') { layer.msg('草稿不可操作'); return; } - 不要用
$(obj.tr).find('button')去查按钮状态,DOM 可能已被重载或缓存失效 - 如果涉及权限叠加(如 status + userRole),把判断逻辑抽成独立函数,确保每次调用都能拿到最新上下文
表格重载后禁用状态丢失怎么办
table.reload() 会清空整个 tbody 并重新渲染,之前靠 JS 动态加的 disabled 或 class 全部消失。Templet 是唯一能随数据自动重建状态的方式,但前提是模板 HTML 必须在 reload 前就存在于 DOM 中。
容易踩的坑:用 $('body').append('<script>...</script>') 动态注入模板 → reload 后找不到 id="actionTpl",直接报错或退化为默认按钮。
- 模板
<script type="text/html" id="actionTpl"></script>必须写在内、table.render()调用之前 - 避免在
done回调里用layui.each遍历 DOM 手动设disabled—— 分页、搜索、reload 后全失效 - 如果用了
skin: 'row'或自定义 CSS,加一行样式防止视觉反馈缺失:button[disabled] { opacity: 0.6; cursor: not-allowed; }
为什么不能用顶部 toolbar 动态禁用按钮
顶部 toolbar 是全局容器,没有 d 上下文,无法知道“当前选中的是哪一行”。你只能监听 row 事件拿 checkStatus,再手动给按钮加 class 和 off('click'),但这个过程极易出错且维护成本高。
真实场景中,95% 的需求其实只需要“某行状态为 X 时,该行的编辑/删除按钮灰掉”,根本不需要全局 toolbar 参与。
- 顶部 toolbar 适合做批量操作(如“批量导出”),不适合做单行状态控制
- 若硬要用,必须监听
table.on('row(test)')和table.on('rowDouble(test)'),再调用table.checkStatus()获取当前选中行,最后用 jQuery 控制按钮状态 - 这种方案在多选、取消选中、分页切换时极易状态不同步,调试困难
最常被忽略的一点:禁用只是 UI 层遮蔽,Layui 的内部事件机制(包括 tool、row、checkbox)完全不感知 disabled。所有后续逻辑——从按钮点击到数据提交——都得你自己兜底校验,不能信 DOM。











