简单记录使用 ElementPlus 的虚拟化树形控件(el-tree-v2)心得

前言

首先在 ElementPlus 官方文档中有 el-tree-v2 使用说明,其实和 el-tree 基本一样。不同就是 el-tree-v2 使用了虚拟滚动技术,正如官方文档所说,不论数据量多大,虚拟树都能毫无压力地处理。

一、示例代码

(1)src/views/Example/ElTreeV2/index.vue

<template>
  <div class="index">
    <el-tree-v2
      :ref="'treeRef'"
      :data="treeData"
      :height="400"
      :indent="26"
      :props="defaultProps"
      :show-checkbox="true"
      :default-expand-all="true"
      :highlight-current="true"
      :expand-on-click-node="false"
    >
      <template #default="{ node, data }">
        <!-- 目录 -->
        <span v-if="data.children != null" @click="handleNodeClick(node, data)" style="display: inline-flex; align-items: center;">
          <i style="display: inline-flex; align-items: center;">
            <svg style="margin: 2px 7px 2px 5px" viewBox="0 0 16 16" width="16" height="16">
              <path d="M14,6 L14,5 L7.58578644,5 L5.58578644,3 L2,3 L2,6 L14,6 Z M14,7 L2,7 L2,13 L14,13 L14,7 Z M1,2 L6,2 L8,4 L15,4 L15,14 L1,14 L1,2 Z" stroke-width="1" fill="#8a8e99" />
            </svg>
          </i>
 
          <small :title="node.label">{{ node.label }}</small>
        </span>
 
        <!-- 文档 -->
        <span v-else style="display: inline-flex; align-items: center;">
          <i style="display: inline-flex; align-items: center;">
            <svg style="margin: 2px 5px 2px 3px" viewBox="0 0 16 16" width="16" height="16">
              <path d="M13,6 L9,6 L9,5 L9,2 L3,2 L3,14 L13,14 L13,6 Z M12.5857864,5 L10,2.41421356 L10,5 L12.5857864,5 Z M2,1 L10,1 L14,5 L14,15 L2,15 L2,1 Z" stroke-width="1" fill="#8a8e99" />
            </svg>
          </i>
 
          <small :title="node.label">{{ node.label }}</small>
        </span>
      </template>
    </el-tree-v2>
 
    <div style="margin: 0 100px">
      <el-button size="small" type="primary" @click="handleGetCheckedNodesClick">
        <el-icon :size="14" style="margin-right: 5px"><Check /></el-icon>
        <small>获取选中节点</small>
      </el-button>
    </div>
  </div>
</template>
 
<script setup>
import { onMounted, onUnmounted, ref, getCurrentInstance } from 'vue'
 
// 代理对象
const { proxy } = getCurrentInstance()
 
// 树组件实例
const treeRef = ref(null)
 
// 树形数据
const treeData = ref(
  [
    {
      id: 1,
      name: '香烟 WiFi 啤酒',
      children: [
        {
          id: 2,
          name: '香烟',
          children: [
            {
              id: 3,
              name: '煊赫门'
            },
            {
              id: 4,
              name: 'ESSE双爆珠'
            }
          ],
        },
        {
          id: 5,
          name: '后端开发技术',
          children: [
            {
              id: 51,
              name: 'Java编程技术',
              children: [
                {
                  id: 511,
                  name: 'SpringBoot框架'
                }
              ]
            },
            {
              id: 52,
              name: 'Python编程技术',
              children: [
                {
                  id: 522,
                  name: 'Django框架'
                }
              ]
            }
          ],
        },
        {
          id: 8,
          name: '数据库',
          children: [
            {
              id: 9,
              name: '关系型数据库',
              children: [
                {
                  id: 10,
                  name: 'MySQL'
                },
                {
                  id: 11,
                  name: 'Oracle'
                }
              ],
            },
            {
              id: 12,
              name: '非关系型数据库',
              children: [
                {
                  id: 13,
                  name: 'Redis'
                },
                {
                  id: 14,
                  name: 'Elasticsearch'
                }
              ],
            }
          ],
        },
        {
          id: 15,
          name: 'AI人工智能'
        },
      ],
    },
    {
      id: 16,
      name: '火腿 iPad 泡面'
    },
  ]
)
 
// 树节点属性映射关系
const defaultProps = {
  children: 'children',
  label: 'name',
}
 
 
/**
 * 点击节点事件句柄方法
 */
const handleNodeClick = (node, data) => {
  console.log(node, data)
}
 
/**
 * 获取选中的节点句柄方法
 */
const handleGetCheckedNodesClick = () => {
  const refs = proxy.$refs
  console.log('refs =>', refs)
 
  const treeRef = refs.treeRef
  console.log('treeRef =>', treeRef)
 
  const checkedNodes = treeRef.getCheckedNodes()
  console.log('checkedNodes =>', checkedNodes)
}
 
onMounted(() => {
 // ...
})
</script>
 
<style lang="less" scoped>
  .index {
    display: flex;
    flex-direction: column;
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #f3f6f8;
 
    :deep(.el-tree) {
      height: 400px;
      margin: 100px 100px 50px 100px;
      border: 1px solid #dcdfe6;
 
      /* ---- ---- ---- ---- ^(节点对齐)---- ---- ---- ---- */
      .el-tree-node {
        
        /* ^ 所有节点 */
        i.el-tree-node__expand-icon {
          padding: 6px;
          margin-right: 5px;
 
          &::before {
            font-family: element-ui-icons;
            font-style: normal;
            content: "\e6d9";
            color: #000000;
            border: 1px solid #606266;
            border-radius: 2px;
          }
 
          svg {
            display: none; // 隐藏所有节点的 svg 图标
          }
        }
        /* / 所有节点 */
 
        /* ^ 已展开的父节点 */
        i.el-tree-node__expand-icon.expanded {
          transform: rotate(0deg); // 取消旋转
          -webkit-transform: rotate(0deg); // 取消旋转
 
          &::before {
            font-family: element-ui-icons;
            font-style: normal;
            content: "\e6d8";
            color: #000000;
            border: 1px solid #606266;
            border-radius: 2px;
          }
        }
        /* / 已展开的父节点 */
 
        /* ^ 叶子节点 */
        i.el-tree-node__expand-icon.is-leaf {
 
          &::before {
            display: none;
          }
        }
        /* / 叶子节点 */
 
        /* ^ 复选框 */
        .el-checkbox {
          margin: 0 5px 0 2px;
 
          .el-checkbox__inner {
            width: 14px;
            height: 14px;
            border-radius: 2px;
            border: 1px solid #bbb;
          }
 
          .el-checkbox__input.is-checked .el-checkbox__inner,
          .el-checkbox__input.is-indeterminate .el-checkbox__inner {
            border: 1px solid #5e7ce0;
          }
        }
        /* / 复选框 */
 
        .el-tree-node__content {
          small {
            font-size: 13px;
            padding-right: 5px;
            transition: all ease 0.1s;
          }
        }
      }
      /* ---- ---- ---- ---- /(节点对齐)---- ---- ---- ---- */
    }
  }
</style>

二、运行效果

 三、参考资料

如何在前端项目中单独引入 ElementUI 图标以及使用_element-icons.woff_帅龍之龍的博客-CSDN博客

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值