el-tree-v2搜索数据不展开问题


el-tree-v2 搜索数据不展开问题

<!-- 结构 -->
<el-input v-model="treeQuery" placeholder="请输入" clearable @input="onQueryChanged" />
<div class="left-tree">
     <el-tree-v2 v-if="data.length"
                 ref="treeRef"
                 :data="data"
                 :props="props"
                 :height="430"
                 :filter-method="filterMethod"
                 :default-expanded-keys="expandedKeys"
                 :expand-on-click-node="false">
            <template #default="{ node, data }">
              <div class="left-slot">
                <div>{{ node.label }} </div>
                <div v-show="data.selectType == 1">
                  <el-link type="primary" @click.stop="moveIn(node, data)">移入</el-link>
                </div>
              </div>
            </template>
     </el-tree-v2>
     <el-empty v-else description="暂无数据" />
</div>
// 逻辑
const originalData = ref([]) //存储完整的数据
const data = ref([]) //存储展示的数据
const treeRef = ref() // tree的ref
// 计算需要展开的数据
const expandedKeys = computed(() => {
  const keys: any = []
  const getKeys = (nodes: any) => {
    nodes.forEach((node: any) => {
      const nodeKey = node[props.value] // 匹配唯一值
      if (treeQuery.value) {
        if (
          node.isSearchMatch ||
          (node.children &&
            node.children.some((child: any) => child.isSearchMatch))
        ) {
          keys.push(nodeKey)
        }
      } else {
        keys.push(nodeKey)
      }
      if (node.children && node.children.length) {
        getKeys(node.children)
      }
    })
  }
  getKeys(data.value)
  return keys
})
// 搜索,进行数据递归匹配
const onQueryChanged = (query: string) => {
  if (!query) {
    data.value = JSON.parse(JSON.stringify(originalData.value))
    return
  }

  // 递归过滤数据
  const filterData = (nodes: any[]): any[] => {
    return nodes
      .filter((node) => {
        const isMatch = filterMethod(query, node)
        if (node.children && node.children.length) {
          const filteredChildren = filterData(node.children)
          node.children = filteredChildren
          // 如果当前节点匹配或者有匹配的子节点,则保留该节点
          return filteredChildren.length > 0 || isMatch
        }
        return isMatch
      })
      .map((node) => ({
        ...node,
        // 添加一个标记,表示这个节点是搜索结果中的匹配节点
        isSearchMatch: filterMethod(query, node), // 是否匹配
      }))
  }

  // 对数据进行过滤
  const filteredData: any = filterData(
    JSON.parse(JSON.stringify(originalData.value))
  )
  data.value = filteredData
}

// 获取tree数据
const treeList = async () => {
  try {
    const res: any = await treeListApi({})
    if (res.code == 200) {
      const treeData = res.data || []
      originalData.value = treeData // 存储完整数据
      data.value = JSON.parse(JSON.stringify(treeData)) // 存储展示的数据
    }
  } catch (error) {
    console.error('获取树数据失败:', error)
  }
}

// tree过滤
const filterMethod = (query: string, node: any) => {
  if (!query) return true
  return node.label.includes(query) // 数据匹配
}

// 监听搜索框数据,等el-tree-v2初始化完成后进行数据展开
watch(
  () => treeQuery.value,
  (newVal) => {
    setTimeout(() => {
      if (treeRef.value) {
        const currentExpandedKeys = expandedKeys.value
        try {
          treeRef.value.setExpandedKeys(currentExpandedKeys) // 手动展开数据
        } catch (error) {
          console.log('展开失败,树组件可能未完全初始化')
        }
      }
    }, 100)
  }
)

文章作者: 冷杨威
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 冷杨威 !
  目录
-->