vue3 + ts 使用 el-tree

实现效果:

代码:

TypeScript 复制代码
<template>

  <!-- el-tree 使用 -->

  <div class="my-tree-container">
    <el-scrollbar height="100%">
      <el-tree ref="treeRef" :data="treeData" node-key="id" @node-click="handleNodeClick" :props="treeProps"
               :show-checkbox="true" :check-strictly="true" :default-expanded-keys="defaultExpandedKeys"
               @check-change="handleCheckChange">
        <template #default="{ node, data }">
          <span class="node-icon"><i class="iconfont" :class="data.icon"/></span>
          <span :class="currentNodeKey === data.id ? 'active-node' : ''">{{ node.label }}</span>
        </template>
      </el-tree>
    </el-scrollbar>
  </div>

</template>

<script setup lang="ts">

import {ref} from "vue";

const treeProps = {
  id: 'id',
  label: 'label',
  children: 'children',
  disabled: 'disabled'
}

const treeData: any[] = [
  {
    id: 1,
    label: 'Level one 1',
    icon: 'icon-houqinguanli',
    children: [
      {
        id: 11,
        label: 'Level two 1-1',
        children: [
          {
            id: 111,
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    id: 2,
    label: 'Level one 2',
    icon: 'icon-caiwuguanli',
    children: [
      {
        id: 21,
        label: 'Level two 2-1',
        children: [
          {
            id: 211,
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        id: 22,
        label: 'Level two 2-2',
        children: [
          {
            id: 221,
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
  {
    id: 3,
    label: 'Level one 3',
    icon: 'icon-nenghaoqingkuang',
    children: [
      {
        id: 31,
        label: 'Level two 3-1',
        children: [
          {
            id: 311,
            label: 'Level three 3-1-1',
          },
        ],
      },
      {
        id: 32,
        label: 'Level two 3-2',
        children: [
          {
            id: 321,
            label: 'Level three 3-2-1',
          },
        ],
      },
    ],
  },
] // 数据

const currentNodeKey = ref<any>(null) // 当前点击的节点的 key【key具体为哪一个属性可通过 node-key 指定】

const defaultExpandedKeys = [1, 2, 3] // 默认展开的节点的 key

const treeRef = ref<any>(null)

const handleNodeClick = (data: any, node: any) => { /* 节点点击事件 */
  currentNodeKey.value = data.id
}

/* 节点勾选事件(当复选框被点击时触发)
* data: 当前点击的节点的数据
* isNodeChecked: 节点本身是否被选中
* hasChildrenChecked: 节点的子树中是否有被选中的节点
*  */
const handleCheckChange = (data: any, node: any, indeterminate: any) => {
  // console.log(data, node, indeterminate)
  const checkedNodes = treeRef.value.getCheckedNodes()
  console.log(checkedNodes, '被选中的节点')
}

// 根据唯一 id 查找树节点
const findNodeById = (id: number, arr: any[]): any => {
  for (let item of arr) {
    if (item.id === id) {
      return item
    }
    if (item.children && item.children.length > 0) {
      const res = findNodeById(id, item.children)
      if (res) {
        return res
      }
    }
  }
}

</script>

<style scoped lang="scss">

.my-tree-container {
  position: absolute;
  top: 100px;
  left: 100px;
  height: 300px; /* tree height needed */
  width: 230px; /* needed */
  background: linear-gradient(180deg, rgba(26, 35, 48, 0.9) 0%, rgba(6, 13, 22, 0.9) 100%);
  opacity: 0.9;
  padding-bottom: 10px;

  .active-node { /* 选中的节点的样式 */
    color: #409EFF;
    background-color: transparent;
  }

  .node-icon {
    margin-right: 10px;
  }

  :deep(.el-tree) {
    background: none;
    color: rgba(206, 207, 209);
    font-size: 16px;
    margin-left: 10px;
    font-weight: lighter;
    font-family: "ResourceHanRoundedCN-Bold", "黑体", Arial, sans-serif;
  }

  :deep(.el-tree-node__content) { // node-height
    height: 35px;
  }

  :deep(.el-tree-node__expand-icon) { /* 隐藏可展开节点前面的箭头 */
    display: none;
  }

  :deep(.el-tree-node__content:hover) {
    background-color: transparent;
    color: #409EFF;
  }

  :deep(.el-tree-node:focus > .el-tree-node__content) { /* 解决点击一个节点后,鼠标移开,修改该节点背景色失效的问题 */
    background: none;
  }

  :deep(.el-icon) {
    font-size: 16px;
  }

  :deep(.el-tree-node) { /* 只有叶子节点显示勾选框 */
    .is-leaf + .el-checkbox {
      display: inline-flex;
    }

    .el-checkbox {
      display: none;
    }
  }

}

</style>
相关推荐
审小匠OpenCPAi3 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution613 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail3 小时前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端
AI多Agent协作实战派4 小时前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
gis开发之家4 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
2601_955760075 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby5 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
触底反弹5 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
耳东小鹿6 小时前
对象常用方法
前端