Virtualized Tree 虚拟化树形控件

305 阅读5分钟

el-treeElement Plus 框架中的树形控件组件,支持虚拟化滚动,适用于大量数据展示的场景。虚拟化滚动可以显著提高性能,避免因数据量过大导致页面卡顿。

el-tree 属性详解

  1. data:

    • 类型: Array
    • 用途: 树形数据。
    • 默认值: []
  2. props:

    • 类型: Object
    • 用途: 配置选项,具体包括 childrenlabeldisabled 等。
    • 默认值: { children: 'children', label: 'label', disabled: 'disabled' }
  3. node-key:

    • 类型: String
    • 用途: 每个树节点用来作为唯一标识的属性,整棵树应该具有不同的 node-key
    • 默认值: 
  4. default-expanded-keys:

    • 类型: Array
    • 用途: 默认展开的节点的 key 的数组。
    • 默认值: []
  5. default-checked-keys:

    • 类型: Array
    • 用途: 默认选中的节点的 key 的数组。
    • 默认值: []
  6. expand-on-click-node:

    • 类型: Boolean
    • 用途: 是否在点击节点的时候展开或者收缩节点。
    • 默认值: true
  7. check-strictly:

    • 类型: Boolean
    • 用途: 在显示复选框的情况下,是否严格的遵循父子不互相关联。
    • 默认值: false
  8. auto-expand-parent:

    • 类型: Boolean
    • 用途: 展开子节点的时候是否自动展开父节点。
    • 默认值: true
  9. default-expand-all:

    • 类型: Boolean
    • 用途: 是否默认展开所有节点。
    • 默认值: false
  10. highlight-current:

    • 类型: Boolean
    • 用途: 是否高亮当前选中节点。
    • 默认值: false
  11. current-node-key:

    • 类型: String | Number
    • 用途: 当前选中节点的 key。
    • 默认值: 
  12. filter-node-method:

    • 类型: Function
    • 用途: 节点过滤函数。
    • 默认值: 
  13. accordion:

    • 类型: Boolean
    • 用途: 是否每次只打开一个同级树节点展开。
    • 默认值: false
  14. indent:

    • 类型: Number
    • 用途: 每级节点的缩进。
    • 默认值: 16
  15. draggable:

    • 类型: Boolean
    • 用途: 是否开启节点拖拽功能。
    • 默认值: false
  16. allow-drop:

    • 类型: Function
    • 用途: 拖拽时判定目标节点能否放置。
    • 默认值: 
  17. allow-drag:

    • 类型: Function
    • 用途: 拖拽时判定节点能否被拖拽。
    • 默认值: 
  18. height:

    • 类型: Number | String
    • 用途: 树的高度,用于虚拟化滚动。
    • 默认值: 

el-tree 事件详解

  1. node-click:

    • 事件名称: node-click
    • 用途: 节点被点击时触发。
    • 参数: 节点数据、节点组件本身、节点的 DOM 元素。
  2. check-change:

    • 事件名称: check-change
    • 用途: 节点选中状态发生变化时触发。
    • 参数: 节点数据、节点本身的选中状态、子树所有节点的选中状态。
  3. current-change:

    • 事件名称: current-change
    • 用途: 当前选中节点变化时触发。
    • 参数: 当前节点数据、当前节点的 DOM 元素。
  4. node-contextmenu:

    • 事件名称: node-contextmenu
    • 用途: 节点右键点击时触发。
    • 参数: 事件对象、节点数据、节点组件本身、节点的 DOM 元素。
  5. node-drag-start:

    • 事件名称: node-drag-start
    • 用途: 节点开始拖拽时触发。
    • 参数: 节点数据、节点组件本身、节点的 DOM 元素。
  6. node-drag-enter:

    • 事件名称: node-drag-enter
    • 用途: 节点进入目标节点时触发。
    • 参数: 拖拽的节点数据、目标节点数据、目标节点组件本身、目标节点的 DOM 元素。
  7. node-drag-leave:

    • 事件名称: node-drag-leave
    • 用途: 节点离开目标节点时触发。
    • 参数: 拖拽的节点数据、目标节点数据、目标节点组件本身、目标节点的 DOM 元素。
  8. node-drag-over:

    • 事件名称: node-drag-over
    • 用途: 节点在目标节点上悬停时触发。
    • 参数: 拖拽的节点数据、目标节点数据、目标节点组件本身、目标节点的 DOM 元素。
  9. node-drag-end:

    • 事件名称: node-drag-end
    • 用途: 节点拖拽结束时触发。
    • 参数: 拖拽的节点数据、目标节点数据、目标节点组件本身、目标节点的 DOM 元素。
  10. node-drop:

    • 事件名称: node-drop
    • 用途: 节点被放置到目标节点时触发。
    • 参数: 拖拽的节点数据、目标节点数据、目标节点组件本身、目标节点的 DOM 元素。

el-tree 插槽详解

  1. default:

    • 插槽名称: default
    • 用途: 自定义节点内容。
  2. prefix:

    • 插槽名称: prefix
    • 用途: 自定义节点前缀内容。
  3. suffix:

    • 插槽名称: suffix
    • 用途: 自定义节点后缀内容。

完整示例代码

<template>
  <div>
    <h2>Virtualized Tree 虚拟化树形控件示例</h2>

    <!-- 虚拟化树形控件 -->
    <el-tree
      :data="treeData"
      :props="defaultProps"
      @node-click="handleNodeClick"
      default-expand-all
      show-checkbox
      node-key="id"
      :expand-on-click-node="false"
      :height="400"
    >
      <template #default="{ node, data }">
        <span>
          <i :class="data.icon"></i>
          {{ node.label }}
        </span>
      </template>
    </el-tree>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElTree } from 'element-plus'

const treeData = ref([])

// 模拟大量数据
onMounted(() => {
  const generateData = (depth, level = 1) => {
    if (level > depth) return [];
    return Array.from({ length: 10 }, (_, index) => ({
      id: `${level}-${index}`,
      label: `节点 ${level}-${index}`,
      icon: 'el-icon-document',
      children: generateData(depth, level + 1)
    }));
  };

  treeData.value = generateData(3);
})

const defaultProps = {
  children: 'children',
  label: 'label'
}

const handleNodeClick = (data) => {
  console.log('节点被点击:', data)
}
</script>

代码解释

  1. 虚拟化树形控件:

    • 使用 el-tree 组件并设置 data 和 props 属性,绑定 node-click 事件,设置 height 属性以启用虚拟化滚动。
    • <el-tree
        :data="treeData"
        :props="defaultProps"
        @node-click="handleNodeClick"
        default-expand-all
        show-checkbox
        node-key="id"
        :expand-on-click-node="false"
        :height="400"
      >
        <template #default="{ node, data }">
          <span>
            <i :class="data.icon"></i>
            {{ node.label }}
          </span>
        </template>
      </el-tree>
      
  2. 模拟大量数据:

    • 使用 onMounted 钩子生成大量数据。
    • const generateData = (depth, level = 1) => {
        if (level > depth) return [];
        return Array.from({ length: 10 }, (_, index) => ({
          id: `${level}-${index}`,
          label: `节点 ${level}-${index}`,
          icon: 'el-icon-document',
          children: generateData(depth, level + 1)
        }));
      };
      
      onMounted(() => {
        treeData.value = generateData(3);
      })
      
  3. 配置选项:

    • 定义 defaultProps 对象,配置树形控件的子节点和标签属性。
    • const defaultProps = {
        children: 'children',
        label: 'label'
      }
      
  4. 节点点击事件:

    • 定义 handleNodeClick 方法,处理节点被点击时的逻辑。
    • const handleNodeClick = (data) => {
        console.log('节点被点击:', data)
      }
      
  5. 自定义节点内容:

    • 使用默认插槽自定义节点内容,添加图标和标签。
    • <template #default="{ node, data }">
        <span>
          <i :class="data.icon"></i>
          {{ node.label }}
        </span>
      </template>
      

自定义样式

  • 自定义树形控件样式:

    • 使用 <style scoped> 自定义树形控件的样式。
    • .el-tree {
        margin-bottom: 20px;
      }