在菜单顶部存在一个输入框,根据输入内容筛菜单。
数据
结构概览
user 商户端
├─ appraise 评价管理
├─ event 事件管理
├─ msg 消息中心
├─ product 产品中心
├─ public 公募市场
├─ list 基金列表
├─ rate 基金评级
├─ compare 基金比较
├─ sa 提审管理
├─ control 产品管控中心
├─ view 产品总览
├─ calendar 产品日历
├─ setting 产品配置管理
├─ rs 反向同步
├─ sys 系统管理
├─ account 账户管理
├─ mac MAC白名单管理
├─ remote 远程管理
...
admin 管理端
├─ customer 商户管理
...
common
├─ log 日志管理
├─ support 支持与服务
...
代码
一般有两种方式来处理(过滤、新增、修改、删除)树形数据:
-
JSON.stringify
、正则、JSON.parse
- 递归
第一种处理通常都相对复杂,并且不可能改变原有数据,但在处理特殊问题时会轻松得多,比如把node.expand
的值由false
修改为true
。
第二种比较常见,也是本次过滤选择的方法。
menusFilter(filterVal, menus) {
const filter = ([start, ...others]) => {
// 数组递归结束
if (start === undefined) {
return []
}
// 为伪菜单
if (start.type === 0) {
return []
}
let hasChild = start.children && start.children.length
// 如果该菜单有子菜单,则过滤其子菜单
if (hasChild) {
return [...filter(start.children), ...filter(others)]
}
// 如果包含过滤值,则返回该菜单
if (start.title.includes(filterVal)) {
return [start, ...filter(others)]
}
// 如果又没子菜单又不包含过滤值,则放弃该菜单
return [...filter(others)]
}
let temp = deepcopy2(menus)
let ret = filter(temp)
// 修改level确保菜单显示一致
ret.forEach(t => {
t.level = -1
})
return ret
}
filter
是本次过滤的核心函数,这其实是第二版,我使用函数式编程的思维重构了它,让它变得更容易理解:
-
filter
总会有一个数组返回值,展开运算符把返回的多个数组合并成一个数组 - 如果
filter
此次执行不能得到确切结果,则在返回数组中继续执行filter
直到返回一个确定数组
代码解释如下:
// 设 menus = [menu1, menu2, menu3],menu1|menu2有子菜单
filter(menus)
// 等同于 =>
[menu1, ...filter(menu2.children), ...filter(menu3.children)]
// filter继续向下分解,子子孙孙都要给翻出来执行一次