【vue3】element el-menu,前端做菜单搜索

需求背景:

前端业务往往菜单业务,其中有一个业务需求就是模糊搜索功能,通常情况下前端拿到接口数据后会缓存本地,无需与后端网络交互就可以实现本地模糊搜索;

方案一:递归+indexof

实现步骤: JS 实现树形结构数据的模糊搜索查询,

即使父节点没有,但子节点含有,父节点仍要返回。

/**
 * 递归tree关键词搜索
 *
 * @param {key} 需要递归的key名
 * @param {value} 需要搜索查询的关键字
 * @param {treeList} 遍历tree列表
 * @return {saveList} 返回查询数组列表
 */

function onFuzzyTreeList (key, value, treeList, saveList = []) {
  return new Promise((resolve, reject) => {
    treeList.forEach(item => {
      if (item[key].indexOf(value) > -1) {
        saveList.push(item);
      } else {
        if (item.children && item.children.length > 0) {
          const _reData = onFuzzyTreeList(key, value, item.children, saveList);
          if (_reData && _reData.length > 0) {
            saveList.push({
              ...item,
              children: _reData
            })
          }
        }
      }
    })

    resolve(saveList)
  })
}


// 调用
onFuzzyTreeList('name', '搜索', treeList)

方案二:抽取1-2级数据重构(推荐)

1.这里只会默认两级数据的情况下

function onFuzzyTreeList(key, value, treeList) {
  // 所有一级导航组成的数组
  const firstArr = treeList.map((it) => ({ name: it.name, id: it.id, level: 1 }))

  // 所有二级导航组成的数组
  const secondArr = treeList.reduce((rd, it1) => {
    if (!it1.children?.length) return rd
    it1.children.forEach((it2) => {
      ;(it2.level = 2), (it2.firstId = it1.id)
    })
    return [...rd, ...it1.children]
  }, [])
  // 一二级导航组成的数组
  const allArr = [...firstArr, ...secondArr]
  function search(key, val) {
    const arr = allArr.filter((it) => it[key].indexOf(val) != -1)
    const firstArrIds = [...new Set(arr.map((it) => it.firstId || it.id))]
    const firstArrResult = firstArr.filter((it) => firstArrIds.includes(it.id))
    firstArrResult.forEach((it) => {
      it.children = arr.filter((it2) => it2.firstId == it.id)
    })
    return firstArrResult
  }
  return search(key, value)
}

方案三:递归+filter+indexof

/** @function 定义前端过滤函数 */
const filterTree = (treeArr, keywords) => {
  function findItem(arr) {
    let res = arr.filter((item) => {
      if (item.children && item.children.length > 0) {
        item.children = childFilter(item.children, keywords)
        console.log(item.children)
      }
      return item.name.indexOf(keywords) !== -1 //不一样的过滤掉
    })
    return res
  }

  function childFilter(childArr, keywords) {
    let res = childArr.filter((item) => {
      // TODO:这里后端说暂时只有2级,所以先预留一下递归逻辑
      if (item.children && item.children.length > 0) {
	      item.children = childFilter(item.children, keywords)
	      return item.name.indexOf(keywords) !== -1
      }
    })
    return res
  }
  return findItem(treeArr)
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停喝水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值