递归组件过滤

当只有一层列表的时候:
const list = computed(() => (
  keyword.value
    ? props.data.filter((item: any) => {
      return item.title.indexOf(keyword.value) != -1
    })
    : props.data
)) 
当有多层列表的时候:
最开始的做法:
const list = computed(() => {
  if (keyword.value) {
    return search(props.data, keyword.value)
  } else {
    return props.data
  }
})
function search(data: any[], keyword: string): any[] {
  let result: any[] = []
  for (const item of data) {
    if (item.title.includes(keyword)) {
      result.push(item)
    }
    if (item.children && item.children.length > 0) {
      const childrenResult = search(item.children, keyword)
      result = result.concat(childrenResult)
    }
  }
  return result
}

有问题,没有按层级结构来显示,全放在同一层显示了

接着实现按层级过滤:
const list = computed(() => {
  if (keyword.value) {
    return search(props.data, keyword.value)
  } else {
    return props.data
  }
})

function search(data: any[], keyword: string): any[] {
  return data.filter(node => {
    // 判断节点是否匹配关键字
    const isMatched = node.title.includes(keyword)
    // 递归过滤子节点
    if (node.children && node.children.length > 0) {
      node.children = search(node.children, keyword)
    }
    // 如果节点或其子节点匹配关键字,则保留该节点
    return isMatched || (node.children && node.children.length > 0)
  })
}

发现还是有问题,在第一次筛选之后,将keyword.value的输入关键词删除,会导致列表显示不全的问题,可能是因为在第一次筛选后,search函数修改了原始数据的结构,导致后续的筛选出现问题。

为了解决这个问题,可以在search函数中对节点的子节点进行浅拷贝,以避免修改原始数据的结构。可以使用Object.assign或扩展运算符…来进行浅拷贝。

最后:
const list = computed(() => {
  if (keyword.value) {
    return search(JSON.parse(JSON.stringify(props.data)), keyword.value)
  } else {
    return props.data
  }
})

function search(data: any[], keyword: string): any[] {
  return data.filter(node => {
    // 判断节点是否匹配关键字
    const isMatched = node.title.includes(keyword)
    // 递归过滤子节点
    if (node.children && node.children.length > 0) {
      node.children = search([...node.children], keyword)
    }
    // 如果节点或其子节点匹配关键字,则保留该节点
    return isMatched || (node.children && node.children.length > 0)
  })
}

在这个修改后的代码中,首先使用JSON.parse(JSON.stringify(props.data))进行深拷贝,以获取原始数据的副本。然后在search函数中,对节点的子节点使用扩展运算符[…node.children]进行浅拷贝,以避免修改原始数据的结构。
这样,在每次筛选时都使用原始数据的副本进行操作,不会影响到原始数据的结构,从而解决了列表显示不全的问题。

ok!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值