Element-plus el-tree 自定义默认展开哪个分支并选中高亮

657 阅读1分钟

需求:设置elTree返回的第一个分支最里面一层,默认展开并高亮选中。
展开的实现方式,可以通过default-expanded-keys,选中高亮可以通过

  1. highlight-current
  2. setCurrentKey

我们要实现的效果如下图 image.png

image.png

(获取树 + 默认展开 + 默认高亮)写成一个通用的 composable,这样其他树遇到也可以用

// useAutoExpandTree.ts
import { ref, nextTick } from 'vue'

/**
 * 自动展开树的某一条分支(默认第一条)并高亮最后一个节点
 */
export function useAutoExpandTree() {
  const treeData = ref<any[]>([])
  const defaultExpandedKeys = ref<string[]>([])
  const treeRef = ref()

  /**
   * 找到某条分支的路径
   * @param node 根节点
   * @param branchIndex 要走第几条分支(0=第一条,1=第二条...)
   */
  const findBranchPath = (node: any, branchIndex = 0): string[] => {
    const path: string[] = []
    let current = node
    while (current) {
      path.push(current.id)
      current = current.children?.[branchIndex]
    }
    return path
  }

  /**
   * 设置树数据,并展开指定分支,选中最后一个节点
   * @param roots 根节点数组
   * @param rootIndex 要选择第几个根节点(默认 0,第一个根节点)
   * @param branchIndex 要展开第几条分支(默认 0,表示第一条)
   */
  const setTreeData = (roots: any[], rootIndex = 0, branchIndex = 0) => {
    treeData.value = roots

    const root = roots[rootIndex]
    if (!root) return

    const branchPath = findBranchPath(root, branchIndex)
    if (branchPath.length === 0) return

    defaultExpandedKeys.value = branchPath

    nextTick(() => {
      treeRef.value?.setCurrentKey(branchPath[branchPath.length - 1])
    })
  }

  return {
    treeData,
    defaultExpandedKeys,
    treeRef,
    setTreeData,
  }
}

在我们的树里面使用

<template>
  <el-tree
    :data="treeData"
    :props="{ label: 'label', value: 'id' }"
    node-key="id"
    :highlight-current="true"
    :default-expanded-keys="defaultExpandedKeys"
    ref="treeRef"
    @node-click="handleTreeNodeClick"
  />
</template>

<script setup lang="ts">
import { useAutoExpandTree } from '@/composables/useAutoExpandTree'
import { fetchClassTree } from '@/api/tree'

const { treeData, defaultExpandedKeys, treeRef, setTreeData } = useAutoExpandTree()

const getLeftTree = () => {
  fetchClassTree({
    projectId: commonStore.currentProject.id,
    name: searchName.value,
  }).then(res => {
    // res.data 是一个数组
    setTreeData(res.data, 0, 0) 
    // 参数解释:
    // res.data       → 整个根节点数组
    // 0              → 选第一个根节点
    // 0              → 展开该根节点的第一条分支
  })
}
</script>