纯前端实现树的搜索筛选功能

文章介绍了如何在React应用中,通过深拷贝和递归函数filterTree,实现在树状数据`treeData`上进行实时搜索并筛选显示的结果。作者展示了如何在用户输入时动态更新节点,以及搜索不同关键词的效果。
摘要由CSDN通过智能技术生成
// 定义树结构,目前是写死的 实际项目中为后端接口返回
const treeData = ref([
  {
    name: 'bububu',
    id: '0-0',
    parentId: '0',
    children: [
      {
        name: 'bbb',
        id: '0-0-0',
        parentId: '0-0',
        children: [
          { name: 'ccc', id: '0-0-0-0', parentId: '0-0-0', },
          { name: 'aaa', id: '0-0-0-1', parentId: '0-0-0', },
        ],
      },
      {
        name: 'abc',
        id: '0-0-1',
        parentId: '0-0',
        children: [{ id: '0-0-1-0', name: 'tttt', parentId: '0-0-1', }],
      },
    ],
  },
])
const searchValue = ref('')

// 深拷贝的方法
const copyList = (arr) => {
  const result = []
  for (const item of arr) {
    result.push(deepclone(item))
  }
  return result
}
const deepclone = (obj) => {
  if (typeof obj === 'object') {
    if (Array.isArray(obj)) {
      return copyList(obj)
    } else {
      const result = {}
      for (const key in obj) {
        result[key] = deepclone(obj[key])
      }
      return result
    }
  } else {
    return obj
  }
}

// enter 触发搜索
const cloneArr = deepclone (treeData.value ) // 克隆数组
const onSearch = () => {
  if (searchValue.value === '') {
    treeData.value = cloneArr
  } else {
    const res = filterTree(treeData.value, searchValue.value)
    treeData.value = res
  }

}


// 实现方式主要为以下函数

// data是树数据 name是需要过滤的内容
function filterTree (treeData, searchValue) {
  let selectIds = []
  function filterId (data, searchValue) {
    let flag = false
    for (let i = 0; i < data.length; i++) {
      const item = data[i]
      if (item.name.indexOf(searchValue) > -1) {
        // 放到数组的第一个
        selectIds.unshift(item.id)
        flag = true
      } else if (item.children && item.children.length) {
        if (filterId(item.children, searchValue)) {
          selectIds.unshift(item.id)
          flag = true
        }
      }
    }
    return flag
  }
  function filterTreeData (data, newData) {
    filterId(treeData, searchValue)
    data.forEach(item => {
      if (selectIds.includes(item.id)) {
        if (item.children && item.children.length) {
          item.children = filterTreeData(item.children, [])
        }
        newData.push(item)
      }
    })
    return newData
  }
  return filterTreeData(treeData, [])
}

html部分

<template>
  <div>
    <a-input-search v-model:value="searchValue" style="margin-bottom: 8px" placeholder="Search"
      @keydown.enter="onSearch" />
    <a-tree :tree-data="treeData" :fieldNames="{
      children: 'children', title: 'name', key: 'id'
    }">
      <template #title="{ name }">
        <span v-if="name.indexOf(searchValue) > -1">
          {{ name.substr(0, name.indexOf(searchValue)) }}
          <span style="color: #f50">{{ searchValue }}</span>
          {{ name.substr(name.indexOf(searchValue) + searchValue.length) }}
        </span>
        <span v-else>{{ name }}</span>
      </template>
    </a-tree>
  </div>
</template>

实现效果

1.筛选之前的数据展示

2.筛选"bb"

3.清空搜索内容

完美!!!!!!!!!!!!!!!!!!!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值