跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Layui如何实现树形表格treeTable的一键全选子节点

Layui treeTable 的 checkAll 不触发深层子节点选中,因其仅作用于已渲染的直接子节点;需用 getChildren 获取全部后代(含懒加载节点),再逐个 setRowChecked 并调用 updateStatus 同步状态。 treeTable 里
checkAll
不触发子节点选中?原因在数据结构和渲染时机 layui 原生
treetable
(v2.7+)不支持「一键全选当前行所有后代子节点」的内置方法,
checkall
只作用于当前层级的直接子节点,且前提是这些子节点已在 dom 中渲染完毕。如果树是懒加载(
islazy
开启)、或子节点初始未展开,
checkall
就不会递归影响深层后代。 实际场景中,用户点击某父节点旁的复选框,期望它连带选中所有子孙节点(包括尚未加载的),这是典型需求,但必须手动补足逻辑。 如何用
setRowChecked
递归标记所有后代节点 核心思路:拿到目标节点的
id
,通过
getChildren
获取全部后代(含懒加载未渲染的节点),再逐个调用
setRowChecked
。注意这不是 DOM 操作,而是操作 treeTable 内部缓存的数据状态。
getChildren
返回的是完整后代节点数组(无论是否已渲染),只要数据里有
children
字段或配置了
url
+
isLazy
,它都能递归遍历出来 必须配合
done
回调或
setTimeout
确保 treeTable 实例已就绪,否则
getChildren
可能返回空 选中状态变更后需显式调用
updateStatus
同步表头和父级半选状态(否则父节点可能仍显示为未选或半选) 示例(点击某行复选框时全选其子孙):
table.on('checkbox(treeTable)', function(obj){ if (!obj.checked) return; // 只处理勾选动作 const id = obj.data.id; const children = table.getChildren(id) || []; // 先标记所有后代为已选 children.forEach(child => { table.setRowChecked({ id: child.id, checked: true }); }); // 更新当前行及所有祖先的 checkbox 状态(含半选逻辑) table.updateStatus(); });
懒加载节点未展开时,
getChildren
还能获取到吗? 能,但有条件:必须已通过
url
配置了子节点接口,且该节点的
isLazy: true
和
hasChild: true
(或后端返回
hasChild: true
)已正确设置。此时
getChildren(id)
会自动发起请求拉取子数据,并返回 Promise;你需要
await
或
.then
处理异步结果。 基于Layui自定义内容轮播插件 基于Layui自定义内容轮播插件是一款表格数据为ajax加载的本地json数据,本地查看会有跨域问题导致数据不能显示。 下载 若节点从未展开过,且未配置
url
或
hasChild
为
false
,
getChildren
直接返回空数组 同步调用
getChildren
时,对懒加载节点会返回
Promise
,不可直接
forEach
,必须
await
推荐统一用
async/await
包裹,避免混用回调和同步逻辑出错 修正后的异步版本片段:
table.on('checkbox(treeTable)', async function(obj){ if (!obj.checked) return; const id = obj.data.id; let children = []; try { children = await table.getChildren(id); // 等待懒加载完成 } catch (e) { console.warn('获取子节点失败', e); return; } children.forEach(child => { table.setRowChecked({ id: child.id, checked: true }); }); table.updateStatus(); });
为什么调用
setRowChecked
后 DOM 没更新? 常见原因是漏掉了
updateStatus()
,或者在 treeTable 实例初始化完成前就执行了操作。Layui 的 treeTable 是「数据驱动视图」,
setRowChecked
只改内存状态,不自动刷新 UI。
updateStatus()
必须显式调用,它会重算每行的
checked
、
indeterminate
状态,并同步到复选框 DOM 确保事件监听绑定在
table.render()
的
done
回调之后,否则
table
实例方法可能未就绪 若表格启用了分页或虚拟滚动,部分节点 DOM 可能被销毁,但
setRowChecked
依然生效——因为它是操作数据源,不是操作 DOM 容易被忽略的一点:父子节点的半选状态(indeterminate)完全由 treeTable 内部根据子节点选中比例计算,你不能手动设
indeterminate: true
,只能靠
updateStatus()
触发重算。

相关文章