vue3+element-plus+el-tree-v2实现节点过滤

发布于:2025-03-23 ⋅ 阅读:(22) ⋅ 点赞:(0)

使用 Element Plus 的 el-tree-v2 实现树形组件节点过滤
需求:通过输入框输入关键字,动态过滤树形节点,只显示匹配的节点及其父节点

实现代码:

<template>
  <div>
    <!-- 输入框用于输入过滤条件 -->
    <el-input
      v-model="filterText"
      placeholder="输入关键字进行过滤"
      clearable
    />

    <!-- el-tree-v2 组件 -->
    <el-tree-v2
      :data="filteredTreeData"
      :props="defaultProps"
      :height="400"
      node-key="id"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

// 过滤条件
const filterText = ref('');

// 原始树形数据
const treeData = ref([
  {
    id: 1,
    label: '一级 1',
    children: [
      {
        id: 4,
        label: '二级 1-1',
        children: [
          { id: 9, label: '三级 1-1-1' },
          { id: 10, label: '三级 1-1-2' },
        ],
      },
    ],
  },
  {
    id: 2,
    label: '一级 2',
    children: [
      { id: 5, label: '二级 2-1' },
      { id: 6, label: '二级 2-2' },
    ],
  },
  {
    id: 3,
    label: '一级 3',
    children: [
      { id: 7, label: '二级 3-1' },
      { id: 8, label: '二级 3-2' },
    ],
  },
]);

// 树形结构的属性配置
const defaultProps = ref({
  children: 'children',
  label: 'label',
});

// 过滤后的树形数据
const filteredTreeData = computed(() => {
  if (!filterText.value) return treeData.value; // 如果过滤条件为空,返回完整数据

  // 递归过滤树形数据
  const filterNode = (node) => {
    // 检查 node.label 是否存在
    if (node.label && node.label.includes(filterText.value)) {
      return true; // 如果当前节点匹配,保留
    }

    if (node.children) {
      node.children = node.children.filter(filterNode); // 递归过滤子节点
      return node.children.length > 0; // 如果子节点有匹配项,保留当前节点
    }

    return false; // 不匹配的节点移除
  };

  // 对树形数据进行深拷贝,避免修改原始数据
  return JSON.parse(JSON.stringify(treeData.value)).filter(filterNode);
});
</script>

<style scoped>
.el-input {
  margin-bottom: 20px;
}
</style>