树组件加一个输入框模糊搜索,根据搜索值去展开匹配到的节点

128 阅读2分钟

1.介绍

功能就是用了一个iview组件的输入框,然后加了一个wacth监听这个输入值的变化,再根据这个变化去调用一个修改展开状态的方法。

2.实现

首先有一个监听,去监听输入框里面值的变化,然后方法里面2次遍历,一次遍历树将匹配到值的节点的状态改变和其向上父节点的id值找到并且储存去重,第二次遍历树的时就去匹配id值是否相同,相同就修改展开状态。其中加了一个 if (searchValueLowerCase)是为了防止清空掉搜索值的全部展开但是这样子清空输入框会保留原来搜索后的展开状态。如果你想清空之后全部折叠回去那就可以加一个清空之后expand展开状态全部变为false

3.源码

 <div class="tree">
      <BInput
        v-model="searchValue"
        placeholder="请输入关键字"
        clearable
        style="width: 300px"
        icon="ios-search"
        size="large"
      />
    </div>

  watch: {
    searchValue(newVal, oldVal) {
      if (newVal !== oldVal) {
        // 当搜索值变化时,更新树节点的expand状态
        this.updateExpandState(newVal)
      }
    }
  },



      // //根据子节点的parentCode(父节点的id)去找父节点
    findNodeById(nodes, id) {
      for (let node of nodes) {
        if (node.id === id) {
          return node
        }
        if (node.children && node.children.length > 0) {
          const found = this.findNodeById(node.children, id)
          if (found) {
            return found
          }
        }
      }
      return null
    },
    //这个时用来更新展开状态的根据搜索框的值
    updateExpandState(searchValue) {
      // 确保searchValue已转换为小写(如果需要模糊匹配不区分大小写)
      const searchValueLowerCase = searchValue.toLowerCase()
      // 用于存储所有需要展开的父节点parentCode的数组
      const expandParentCodes = []
      const expandParentCodesSet = new Set() // 使用Set去重
      // 递归函数来更新树中节点的expand状态
      const traverseTree = nodes => {
        nodes.forEach(node => {
          if (searchValueLowerCase) {
            // 检查节点的标题是否包含搜索值
            if (node.title.toLowerCase().includes(searchValueLowerCase)) {
              node.expand = true // 设置匹配的节点为展开状态
              // 收集需要展开的父节点ID,需要筛选掉重复的id
              if (node.parentCode && node.parentCode != 0) {
                const parentNode = this.findNodeById(this.数据源, node.parentCode)
                expandParentCodesSet.add(parentNode.id) // 将父节点的id添加到Set中
              }
            }
            // 如果节点有子节点,递归处理子节点
            if (node.children && node.children.length > 0) {
              traverseTree(node.children)
            }
          }
        })
      }
      // 从根节点开始遍历树
      traverseTree(this.数据源)
      // 将Set转换为数组
      expandParentCodes.push(...expandParentCodesSet)
      // 遍历树的所有节点,检查是否有节点的id与expandParentCodes中的parentCode匹配
      const traverseAndUpdateExpand = nodes => {
        nodes.forEach(node => {
          // 检查当前节点的id是否在expandParentCodes中
          if (expandParentCodes.includes(node.id)) {
            node.expand = true // 设置父节点为展开状态
          }
        })
      }
      // 从根节点开始更新expand状态
      traverseAndUpdateExpand(this.数据源)
    }