技术需求:实现可搜索缩进下拉菜单,匹配父项时展示子项
可搜索缩进下拉菜单实现方案
一、定义层级化数据结构
先把下拉选项整理成包含父子关联的结构化数据,方便后续处理:
const menuItems = [ { id: 1, label: 'USA', parentId: null, children: [ { id: 11, label: 'Austin', parentId: 1 }, { id: 12, label: 'New York', parentId: 1 } ] }, { id: 2, label: 'Canada', parentId: null, children: [ { id: 21, label: 'Toronto', parentId: 2 } ] } ];
二、调整搜索过滤逻辑
针对两种核心场景实现过滤:
- 父项匹配时,保留父项及所有子项
- 子项匹配时,仅保留该匹配子项
核心过滤函数示例:
function filterMenuItems(searchQuery) { const query = searchQuery.toLowerCase().trim(); if (!query) return menuItems; const result = []; menuItems.forEach(parent => { const parentMatches = parent.label.toLowerCase().includes(query); const matchedChildren = parent.children?.filter(child => child.label.toLowerCase().includes(query) ) || []; // 父项匹配时,添加父项+全部子项 if (parentMatches) { result.push({ ...parent }); } // 子项匹配时,仅添加匹配的子项,并标记层级用于缩进 else if (matchedChildren.length > 0) { matchedChildren.forEach(child => { result.push({ ...child, level: 1 }); }); } }); return result; }
三、实现缩进样式渲染
通过CSS层级类控制缩进,渲染时绑定对应类名:
.menu-item { padding: 8px 12px; cursor: pointer; } .menu-item.level-1 { padding-left: 24px; /* 子项缩进距离 */ }
以Vue为例的渲染逻辑:
<div class="dropdown-menu"> <div v-for="item in filteredItems" :key="item.id" :class="`menu-item ${item.level ? 'level-' + item.level : ''}`" > {{ item.label }} </div> </div>
四、异步搜索适配
如果是接口异步返回数据,只需在数据加载完成后,先整理成上述层级结构,再调用过滤函数即可,逻辑和同步场景完全一致。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

