必须用templet自定义checkbox列并显式写disabled和checked属性,禁用依据为d.status等行数据字段,且table.checkstatus()结果需手动过滤掉status为'closed'的行。
用 templet 渲染带 disabled 的 checkbox 最可靠
直接写 {type: 'checkbox'} 无法按行禁用,必须放弃内置 checkbox 类型,改用普通列 + 自定义模板。关键点有三个:name="laytablecheckbox" 不能丢,disabled 要根据行数据动态写,checked 也要显式控制。
示例模板:
<script type="text/html" id="checkboxTpl">
<input type="checkbox" name="layTableCheckbox"
{{# if(d.status === 'closed'){ }} disabled {{# } }}
{{# if(d.LAY_CHECKED){ }} checked {{# } }}>
</script>
-
d.status === 'closed'是判断条件,换成你自己的字段和值即可 - 必须用
d.LAY_CHECKED(不是d.layChecked)来读取 Layui 内部选中状态 - 模板里没写
id或lay-id时,Layui 可能漏触发事件,建议加上lay-id="{{d.id}}"
table.checkStatus() 返回结果仍含禁用行,必须手动过滤
哪怕 checkbox 灰了、点了没反应,table.checkStatus('demo').data 还是会把它们全塞进来——Layui 不管 disabled,只看 DOM 元素是否存在。
真实可用的已勾选数据得自己筛:
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 - 如果用了
checkStrictly: true,父子联动逻辑不受影响,但结果一样要过滤 - 导出或提交前不做过滤,禁用行就真被当有效数据发出去了
点击操作按钮时别让行跟着被选中
操作列按钮(比如 lay-event="edit")点下去,行却自动勾上了——这是事件冒泡导致的,默认行为没被拦住。
在 table.on('tool(filter)') 回调里第一行加 layui.stope(event):
table.on('tool(test)', function(obj){
var event = obj.event;
layui.stope(event); // ✅ 必须放第一行
if(event === 'edit'){
console.log(obj.data);
}
});
-
event必须从obj.event拿,传错参数stope就失效 - 别写
onclick="return false",Layui 事件是委托绑定的,内联写法压根不生效 - 即使 checkbox 已
disabled,tr 本身点击仍会触发选中,所以这个拦截不能省
checkRender 仅适用于 Layui ≥2.8.0,且每行都执行可能卡顿
如果你用的是 2.8.0 或更高版本,checkRender 是个更轻量的替代方案,但它只在 checkbox 列里生效,且返回的必须是原生 <input> 字符串。
{type: 'checkbox', checkRender: function(data) {
if(data.status === 'closed') {
return '<input type="checkbox" disabled>';
}
return '<input type="checkbox">';
}}
- 旧版本(如 2.7.x)调用会报
checkRender is not a function错误 - 数据量大时(>1000 行),每行都拼字符串,渲染略慢;此时
templet更可控 - 禁用样式依赖 Layui 默认 CSS,若项目覆盖了
.layui-form-checkbox[disabled],视觉上可能看不出灰显
真正容易被忽略的是:禁用只是 UI 层遮蔽,Layui 的状态管理完全 unaware —— 所有涉及“已选中”的逻辑,都得自己补一层数据过滤,没有例外。











