Layui导航菜单本身不支持搜索过滤,所谓“导航菜单搜索”实为对tree组件或自定义列表的手动增强;需用tree.render()替代原生导航,监听输入事件、递归过滤数据并标记spread: true后reload,同时添加防抖与展开态同步逻辑。

layui导航菜单本身不支持搜索过滤
layui没有提供类似nav或menu组件的内置搜索能力,官方文档和源码中均无search、filter等配置项。所谓“导航菜单搜索”,实际是开发者对tree(树形结构)或自定义ul>li列表的手动增强——因为真正需要搜索的,从来不是顶部横排导航栏(如首页/产品/关于),而是左侧可折叠的多级菜单栏(即权限菜单、功能目录等)。这类结构本质是树,必须按树形组件逻辑处理。
用tree.render()替代原生导航并启用搜索
如果你的“导航菜单”是通过tree.render()渲染的(推荐做法),那搜索就是对树数据的过滤。核心不是加输入框,而是重生成符合关键词的子树,并保持祖先节点展开:
- 原始数据必须带
name或title字段(用于匹配),且有children嵌套结构 - 监听搜索框
input事件,调用递归过滤函数(如filterTreeData(originalData, keyword)) - 过滤后必须给匹配节点及其所有父节点打标记(例如加
spread: true),否则reload时节点默认收起,用户看不到结果 - 调用
tree.reload({ data: filteredData }),不要复用原始数据引用,避免状态污染
手动插入搜索框并绑定防抖事件
别在tree.render()配置里硬塞search: true——它不存在。正确做法是独立放一个输入框,用事件代理绑定:
- HTML里写:
<input type="text" class="nav-search">,放在tree容器上方 - JS中用
layui.$(document).on('input', '.nav-search', debounce(function(e) { ... }, 200)),防抖值设200ms足够响应又不卡顿 - 取值用
e.target.value.trim(),空字符串时直接tree.reload({ data: originalData })恢复全量 - 注意:不要在
templet里拼搜索框,tree不支持表头式templet,会报错或不渲染
容易被忽略的展开态与性能细节
搜索后节点“找得到但点不开”是最高频问题,根源在展开状态未同步:
- 过滤后的
filteredData中,每个匹配节点必须显式设置spread: true,否则即使数据存在,UI仍显示为收起状态 - 如果原始数据量超500条,递归遍历+正则匹配可能卡顿,建议对
name字段预建拼音索引(如用pinyin库转存py字段),搜索时查node.py.includes(keyword) - CSS需限制搜索框高度:
.nav-search { height: 32px; padding: 0 12px; },否则撑开导航栏间距,破坏整体对齐


















