必须用templet自定义checkbox列并显式写disabled属性,因layui内置{type:'checkbox'}不读取数据字段的disabled,重绘后失效;需保留name="laytablecheckbox"、动态判断disabled与checked、过滤table.checkstatus结果中的禁用行。

必须用 templet 自定义 checkbox 列并显式写 disabled 属性,内置 {type: 'checkbox'} 列不支持按行禁用——这是唯一可靠方式。
为什么不能直接在列配置里加 disabled: true
因为 Layui 的 {type: 'checkbox'} 是内部封装渲染逻辑,它根本不读取你数据对象里的 disabled 字段。你写 d.disabled = true 或在 cols 里硬写 disabled: true,对 DOM 渲染和事件响应都完全无效。表格重绘、翻页、table.reload() 后,这些设置都会丢失。
- 常见错误现象:checkbox 看起来灰了但点一下仍能勾上;或者根本没变化,始终可选
- 根本原因:Layui 不会把行数据字段映射到 input 的
disabled属性,只认自己生成的 DOM 结构 - 解决方案只有一条路:放弃内置 checkbox 类型,改用普通列 +
templet手动拼<input>
templet 模板里怎么写才生效
关键不是“能不能写”,而是“写对哪几个点”。漏掉任意一个,禁用就形同虚设:
-
name="layTableCheckbox"必须保留——这是 Layui 内部识别多选行的硬性约定,写成name="xxx"或漏掉,table.checkStatus()就拿不到这行 -
disabled要根据当前行数据动态判断,比如{{# if(d.status === 'closed'){ }} disabled {{# } }},不能写死,也不能依赖外部变量 -
checked也得显式控制,别指望d.layChecked自动生效;要用d.LAY_CHECKED(注意大小写),否则视觉状态和内部字段不同步 - 建议加上
lay-id="{{d.id}}"或data-id="{{d.id}}",避免事件绑定漏触发,尤其在分页或排序后
示例模板:
<script type="text/html" id="checkboxTpl">
<input type="checkbox" name="layTableCheckbox"
{{# if(d.status === 'closed'){ }} disabled {{# } }}
{{# if(d.LAY_CHECKED){ }} checked {{# } }}
lay-id="{{d.id}}">
</script>
table.checkStatus() 返回的数据还包含禁用行?
是的,而且这是最常被忽略的致命点。Layui 完全不感知 disabled,只要 DOM 里有这个 <input> 元素,不管它灰不灰、点不点得动,table.checkStatus('demo').data 都会把它塞进去。
- 导出、批量提交、权限校验前,如果直接用
res.data,禁用行就会被当成有效数据发出去 - 正确做法是手动过滤缓存:
const cache = table.cache['demo']; const validChecked = cache.filter(d => d.status !== 'closed' && d.LAY_CHECKED); - 全选判断不能看
res.count,得比对:validChecked.length === cache.filter(d => d.status !== 'closed').length - 监听
checkbox事件时第一句就要拦截:if (obj.disabled) return;,否则后续逻辑照样执行
点击操作按钮时行却自动勾上了?
这是事件冒泡导致的。操作列按钮(比如 lay-event="edit")点击时,事件会向上冒泡到 <tr>,触发默认的行选中行为。<ul>
<li>解决方法:在 <code>table.on('tool(filter)') 回调第一行加 layui.stope(event)
event 必须从 obj.event 拿,写成 layui.stope(e) 或传错参数就失效onclick="return false",Layui 是事件委托绑定,内联写法压根不生效disabled,<tr> 点击仍会触发选中,所以这个拦截不能省<p>禁用只是 UI 层遮罩,Layui 的状态管理、父子联动、分页缓存、甚至 <code>table.reload() 后的恢复,全都无视 disabled。你写的每一处“已选中”逻辑,都得自己加一层数据校验——没有例外。











