layui 无内置下拉树组件,需用 tree 组件配合自定义弹层实现:将 tree 渲染到独立隐藏容器,通过按钮控制显隐;showcheckbox: true 必须在 render 配置中设为布尔 true;节点需含 id 字段且 children 为数组;点击标题勾选需委托事件调用 setchecked();getchecked() 需传 render 时指定的实例 id。
直接用 tree 组件 + 自定义弹层就能实现,layui 本身不提供“下拉树”这种封装组件,但组合 showcheckbox: true 和弹出控制逻辑足够稳定可靠。
如何让 tree 渲染成可点击展开的下拉式树
本质是把 tree.render() 渲染到一个隐藏容器里,再通过按钮/输入框触发显隐。关键不是改 tree,而是控制它的父容器显示逻辑。
- 树容器(如
#dept_tree)必须放在一个独立<div> 内,不要嵌套在表单控件里,否则定位和层级容易错乱 <li>用 CSS 控制初始隐藏:<code>style="display:none; position:absolute; z-index:9999; border:1px solid #e6e6e6; background:#fff;" - 绑定点击事件时,注意避免重复渲染:每次 show 前先检查是否已渲染过,未渲染则调用
tree.render(),已渲染则只show() - 点击遮罩或外部区域时,用
$(document).on('click', ...)关闭弹层,但要e.stopPropagation()阻止树内点击冒泡关闭 - 值必须是布尔
true,传"true"、1或省略都会失效 - 节点数据中每个对象必须含
id字段,否则父子联动计算会跳过该节点 -
children必须是数组(哪怕空数组[]),写成null或不写,子节点就不会参与勾选同步 - 必须等 tree 渲染完成后再绑定事件,推荐放在
done回调里,或用setTimeout(() => {}, 0) - 选择器用
.layui-tree-txt(Layui 2.8+),旧版本可能需.layui-tree-txt > span - 通过
$(e.currentTarget).closest('.layui-tree-node').data('id')提取节点 ID,确保和 data 中的id类型一致(建议统一转成字符串) - 调用
tree.setChecked('yourTreeId', [idValue]),哪怕只勾一个也要传数组 - render 时必须显式写
id: 'deptTree',这个id是内部索引键,和 DOM 的id无关 - 获取时必须传同名字符串:
tree.getChecked('deptTree'),传'#dept_tree'或漏传都会失败 - 返回的是原始节点对象数组,含
id、title等字段,不含额外包装;如需提交后端,直接JSON.stringify()即可 - 别在
oncheck里频繁调用getChecked()——它每次都会遍历全树,高频触发易卡顿
为什么 showCheckbox: true 必须写在 render 配置里
因为 showCheckbox 是初始化开关,不是运行时 toggle 方法。漏掉它,整个复选框 DOM 根本不会生成,后续任何 JS 操作都无效。
点击节点标题时如何触发勾选(非 checkbox 区域)
Layui 默认只响应复选框本身的点击,标题区域点击无状态变更。要支持“点文字就勾选”,得手动委托事件并调用 tree.setChecked()。
获取选中数据时最容易踩的坑
tree.getChecked() 返回空或报错,90% 是因为没配实例 id,或者配了但调用时传错名。
真正麻烦的从来不是怎么写,而是节点 id 类型不一致、children 不是数组、或者弹层 z-index 被其他组件压住——这些细节一错,整棵树看起来就像“不工作”。











