layui tree 的 showSearch: true 仅渲染搜索框且无过滤逻辑,需手动实现递归筛选、路径保留、深拷贝、展开状态缓存恢复及防抖,并注意字段名、大小写和高亮细节。

showSearch: true 为什么没反应
因为 layui tree 的 showSearch: true 只是插入一个输入框,不绑定任何逻辑。2.8.0+ 版本能渲染出搜索框,但输入后树不会自动过滤;2.7.x 及更早版本压根不识别这个配置,连框都不会出现。控制台里搜不到 tree.on('search') 这类 API——它根本不存在。
filterTreeData 必须递归保留父链
只筛出 name 包含关键词的节点会断路径。比如搜“运维”,匹配到 ID=105 的子节点,但它的父节点(ID=102、ID=101)必须一并保留在新数据里,否则 reload 后看不到层级关系。
- 每个节点加临时字段如
match: true,表示自身或任意子孙匹配 - 判断条件不能只写
node.name.includes(keyword),还得递归检查children里是否有match === true的子项 - 生成新数据时跳过
match === false && (!node.children || node.children.length === 0)的节点 - 别直接改原始
data,用JSON.parse(JSON.stringify(originalData))深拷贝隔离副作用
reload 后展开状态丢失怎么恢复
tree.reload() 会清空所有 DOM 状态,包括用户手动展开过的节点。如果希望搜完仍保持父路径可见,得自己缓存再恢复:
- 搜索前调用
tree.getChecked('id')或遍历$('[data-id]').filter(':visible')获取已展开节点 ID 列表 - 在
reload的done回调里,用tree.expand(id, true)逐个展开 - 若启用了
accordion: true,要倒序展开(先子后父),否则兄弟节点会被自动收起 - 必须加防抖(如 300ms),否则连续输入触发多次 reload,展开恢复逻辑可能被覆盖
大小写、字段名、高亮这些细节最容易漏
硬写 node.title 就会匹配失败——你的数据里可能是 label、nodeName 或 text;直接操作 innerHTML 插入 <mark> 容易嵌套污染 DOM。
- 匹配前统一转小写:
node.name?.toLowerCase().includes(keyword.toLowerCase()) - 高亮建议用 CSS 类 +
textContent替换,避免反复操作 HTML 结构 - 如果用了
textKey: 'label'渲染,filter 函数里也得读node.label,不是默认的title - 搜索后想真正选中节点,别靠文本反推 ID,应递归提取匹配节点的完整对象,再传给
tree.setChecked()


















