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>
相关推荐
CarIise5 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢6 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
IT_陈寒6 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
小灰灰搞电子7 小时前
Rust+Slint 实现温度计源码分享
前端·rust·slint
计算机魔术师7 小时前
面壁智能 OpenBMB 推出 MathForm,面向 Lean 4 数学自动形式化的开源框架、数据集与模型
前端
NeilCarmack7 小时前
Deepseek-harness增加桌面版端序列:第 2 讲 · spawn Electron:当前进程如何“交棒“
前端·javascript·electron
上海魁鲸科技有限公司8 小时前
APS高级排产系统到底有什么用?一文讲清功能、选型与落地建议
前端·microsoft·excel
陈随易8 小时前
Bun v1.4 更新总结:把浏览器、图片、定时任务和工程工具都装进一个运行时
前端·后端·程序员
东风破_9 小时前
TypeScript 高级类型进阶:keyof、Exclude、Record 与类型组合思想
前端·后端·typescript
DS随心转插件10 小时前
Grok生成的html怎么导出——AI导出鸭:大模型结构化输出的“最后一公里”工程化解构
前端·人工智能·ai·html·豆包·deepseek·ai导出鸭