element-plus elplus el-tree三种图标自定义 并且点击图标展开收起 点击文字获取数据

news2024/9/22 2:07:19

前言
公司需求,需要实现如下样式的树形列表 (基于vue3 + element-plus)
在这里插入图片描述
当节点展开时,显示展开的文件夹图标,当节点收起时显示收起的文件夹,最后一级显示文件样式
废话没有了, 代码如下

<!-- 树形列表组件 -->
<template>
  <div class="tree-input" v-if="filter">
    <el-input v-model="filterText" clearable placeholder="输入关键字" />
  </div>
  <el-tree :data="treeDataList" highlight-current :node-key="nodeKey"
   :current-node-key="currentNodekey" :default-expanded-keys="defaultExpandedList"
  ref="treeRef" icon="none" :filter-node-method="fliterNode" :expand-on-click-node="false" >
    <template #default="{ data }">
      <div class="com-tree">
        <el-icon size="13" class="com-tree-icon" @click="toggleChild(data)" >
          <Document v-if="data.isLast" />
          <FolderOpened v-else-if="data.opened" />
          <Folder v-else />
        </el-icon>
        <div class="com-tree-text" @click="handleNodeClick(data)" >{{ data[prop.label] }}</div>
      </div>
    </template>
  </el-tree>
</template>

<script setup>
import { Folder, FolderOpened, Document } from "@element-plus/icons-vue"
import { compileTreeData } from '@/utils/compileTreeData.js'

const props = defineProps({
  // 树内容
  treeData: {
    type: Array,
    default: []
  },
  // 过滤器
  filter: {
    type: Boolean,
    default: false
  },
  // 树形结构属性绑定值
  prop: {
    type: Object,
    default: {
      label: 'label'
    }
  },
  // 树节点唯一绑定值 注意是唯一值 不是value值
  nodeKey: {
    type: String,
    default: 'id'
  },
  // 当前选中的树节点 即nodeKey
  currentNodekey: {
    type: [String, Number],
    default: ''
  },
  // 默认展开的树节点列表  即nodeKey组成的列表
  defaultExpandedList: {
    type: Array,
    default: []
  },
})


// 树dom
const treeRef = ref()
const treeDataList = ref([])

// 当有默认展开时,切换展开图标样式
const expandIcon = () => {
  treeDataList.value.map(item => {
    if (props.defaultExpandedList.includes(item[props.nodeKey])) {
      item.opened = true
    }
  })
}

// 监听传入的树形结构, 并且进行转化
watch(() => props.treeData, newValue => {
  if (newValue.length > 0) {
    const treeDataTemp = [...newValue]
    // 获得新的树形结构
    treeDataList.value = compileTreeData(treeDataTemp)

    // 如果传入了默认展开
    if (props.defaultExpandedList.length > 0) {
      expandIcon() // 切换展开图标样式
    }
  }
}, {
  immediate: true
})

const emits = defineEmits(['node-click'])

// 点击图标
const toggleChild = (data) => {
  let nodes = treeRef.value.store.nodesMap
  // console.log('nodes', nodes)
  for (let i in nodes) {
    const item = nodes[i]
    if (item.data[props.nodeKey] === data[props.nodeKey] && !item.data.isLast) {
      data.opened = !data.opened // 图标切换
      item.expanded = data.opened // 展开或收起子节点
    }
  }
}

const handleNodeClick = (data) => {
  emits('node-click', data)
}


// 树过滤文本 
const filterText = ref('')
watch(filterText, (val) => {
  treeRef.value.filter(val)
})
// 树过滤
const fliterNode = (value, data) => {
  if (!value) return true
  return data.label.includes(value)
}
// 折叠全部节点
const setAllFold = () => {
  let nodes = treeRef.value.store.nodesMap;
    for (const node in nodes) {
      nodes[node].expanded = false;
    }
}


// 清除输入框 折叠所有节点
const clearInput = () => {
  filterText.value = ''
  setAllFold() // 折叠所有节点
}

defineExpose({
  clearInput
})
</script>

<style lang="scss" scoped>
.tree-input {
  padding: 0 24px 10px;
}
.com-tree {
  display: flex;
  align-items: center;
  &-icon {
    margin-right: 10px;
    flex: 0 0 auto;
  }
  &-text {
    flex: 1;
  }
}
</style>

用到的JS

compileTreeData.js

let topId = '' // 最高级ID 考虑到点击很底层需要用到最高层id 而后端没有返回
const deepLoop = (treeData, isChild) => { // 一个递归
  if (treeData && Array.isArray(treeData)) {
    treeData.map(item => {
      if (!isChild) { // 进入if 表示当前item为顶级
        topId = item.id
      }
      item.opened = false // 默认全部都是收起状态
      item.topId = topId // 不是顶级的 赋值顶级ID 
      if (item.children && item.children.length > 0) { // 有子元素
        item.isLast = false // 不是最后一级
        deepLoop(item.children, true) // 进行递归
      }else { // 是最后一级
        item.isLast = true 
      }
    })
    return treeData
  }
}


export const compileTreeData = (treeData)=> {
  return deepLoop(treeData)
}

还有一件事

有的时候文字很短,不好点击,需要点击文字右侧空白也能触发数据回传事件
那么你需要想办法 覆盖这个类 ---- .el-tree-node__label
覆盖后即可

/* 我的写法 */
.my-app .el-tree-node__label {
  flex: 1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69523.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue学习:回顾Object.defineProperty(给对象添加或者定义属性的)

<script>//定义对象let person{name:李四,sex:"男"}Object.defineProperty(person,age,{value:18});//参数:添加属性的对象 添加的属性名 配置项console.log(person)</script> 颜色不同&#xff1a;说明了age不可以枚举age属性不参与遍历 Object.keys(…

电脑屏幕录制怎么弄?电脑上怎么录制屏幕, 3个实用方法

对于日常办公的小伙伴来说&#xff0c;电脑、键盘、鼠标等办公设备都是不可分割的。事实上&#xff0c;不仅仅是在日常办公&#xff0c;在很多业余的活动中&#xff0c;也会使用到电脑设备。在使用电脑的时候&#xff0c;会经常有需要录制电脑屏幕的情况&#xff0c;比如记录会…

阿里云Linux热扩容云盘(growpart和resize2fs工具)

阿里云linux机器系统盘空间不够进行扩容 一、扩容物理盘 阿里云控制台在线扩容完成 二、安装growpart工具和resize2fs工具 [rootA ~]# yum install cloud-utils-growpart [rootA ~]# yum install xfsprogs 三、检查扩容磁盘属性 1、检查云盘大小 /dev/vda1显示容量为20G(在线…

Properties类的使用

Properties类是一个配置文件类&#xff0c;主要作用就是用来封装配置文件&#xff0c;将配置文件加载成为一个Properties对象。 注意&#xff1a;Properties类一般用来加载 .properties配置文件 首先看一下.properties配置文件的样子 driverClassNamecom.mysql.cj.jdbc.Drive…

电力系统潮流【牛顿-拉夫逊法】(4节点、5节点、6节点、9节点)(Matlab代码实现)

目录 1 概述 2 电力系统潮流计算概述 2.1 电力潮流发展进程 2.2牛顿拉夫逊法潮流计算 3 仿真结果 4 Matlab代码及文章讲解 &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;⛳️⛳️⛳️ ​ 1 概述 最初&#xff0c;电力系统潮流计算是通过人工手算的。后…

Java内存区域与内存分配策略

java很聪明&#xff0c;它将手动改为自动&#xff0c;把内存的控制权交给了虚拟机&#xff0c;下面我们就来探究一下JVM是怎么进行自动内存管理的。 手动内存管理分为两部分&#xff1a;给对象分配内存和回收分配给对象的内存。 一、运行时数据区域 线程公有 在运行时数据区中…

基础入门 - SpringBoot 底层注解

目录 1、SpringBoot特点 1.1、依赖管理 1.2、自动配置 2、容器功能 2.1、组件添加 1、Configuration Spring Boot 在底层 Configuration 的两个配置 2、Import 3、Conditional 2.2、原生配置文件引入 1、ImportResource 2.3、配置绑定 1、ConfigurationProperties …

前端开发踩坑笔记(2022-11)

文章目录1、Mac上SourceTree更新已删除的远端分支和tag2、echarts x轴文字显示不全&#xff08;解决方案&#xff09;3、如何渲染多行多列的表格&#xff08;非固定的行数和列数&#xff09;4、umy-ui标题过长或内容过长时的处理5、dateRange的时间选择只能选择一个周6、如何将…

Servlet API 详解

目录 一、HttpServlet ① init() 方法 ② service() 方法 ③ destroy() 方法 ④ doGet()方法 ⑤ doPost()方法 ⑥ doPut/deDelete/doOptions 常见面试题&#xff1a; 请你谈谈Servlet的生命周期 二、Http请求&#xff1a;HttpServletRequest 1. 获取请求行信息 2. 获…

一个redux使用案例模板

目录 redux 纯函数和高阶函数&#xff1a; redux 开发工具使用 react-redux redux 1. 结构&#xff1a; count--index.jsx import React, { Component } from react import store from ../../redux/store import { acDecrement,acIncrement,acAsyncIncrement } from ../..…

不会向上管理的人,做不好项目经理和PMO【附具体行动清单】

在职场中&#xff0c;向上管理基本是最重要的一件事儿&#xff0c;升职涨薪奖金都离不开向上管理&#xff01;当你的向上管理做得好&#xff0c;机会都会迎面扑来。 你是不是也遇到过被领导批评时&#xff0c;感到非常委屈或愤怒&#xff0c;情绪经常被领导左右&#xff0c;那…

Three.js一学就会系列:02 画线

系列文章目录 Three.js一学就会系列&#xff1a;01 第一个3D网站 文章目录系列文章目录[Three.js一学就会系列&#xff1a;01 第一个3D网站](https://blog.csdn.net/u012551928/article/details/128205373)前言一、省略部分二、使用方法创建一个场景创建一个透视摄像机将渲染器…

详解CSS层叠上下文(解析z-index不生效的原因)

为什么会有层叠上下文 在CSS2.1规范中&#xff0c;每个盒模型的位置是三维的&#xff0c;分别是平面画布上的X轴&#xff0c;Y轴以及表示层叠的Z轴。一般情况下&#xff0c;元素在页面上沿X轴Y轴平铺&#xff0c;我们察觉不到它们在Z轴上的层叠关系。而一旦元素发生堆叠&#x…

查询网站的谷歌PR权重复杂吗?查询谷歌PR权重最简单的方法

查询网站的谷歌PR权重复杂吗&#xff1f;用对方法一点也不复杂哦! 查询谷歌PR权重最简单的方法——用网站批量查询工具。 网站批量查询工具根据网站的域名可以查询到网站的权重值、网站信息、域名信息、域名备案情况、域名是否安全&#xff0c;来作为网站数据分析的参考。 具体…

C语言基础7:结构体类型、声明、成员类型、定义、初始化、成员访问、传参

文章目录C语言基础7&#xff1a;结构体类型、声明、成员类型、定义、初始化、成员访问、传参1. 结构体类型的声明1.1 结构体的基础知识1.2 结构体的声明1.3 结构体成员的类型1.4 结构体变量的定义和初始化2. 结构体成员访问4. 结构体传参C语言基础7&#xff1a;结构体类型、声明…

SAP S4HANA MM模块后台配置详解

目录 1. 常规设置 1.1 定义国家 1.2.计量单位配置 1.3.货币设置 1.4.维护日历 1.4.1 概念及功能说明 1.4.2 业务示例 1.4.3 配置步骤 2. 企业结构 2.1 定义和分配公司 2.2 设定评估级别、定义/分配工厂 2.2.1. 概念及功能说明 2.2.1. 业务示例 2.2.2. 配置步…

java 八股文

java 八股文 java篇 java 面向对象有哪些特征 封装 多态和继承 arrayList 和 LinkedList 的区别 数据结构不同&#xff0c;一个是数组一个是链表 arrayList 适合 随机访问 读多&#xff0c;插入和删除少 LinkedList 适合插入 和删除 多&#xff0c;按次序遍历的情况 再…

数据结构实验-折半插入排序-双向冒泡排序

目录 分析&#xff1a; 折半插入排序 双向冒泡排序 折半插入排序 思想&#xff1a; 代码 运行结果 双向冒泡排序 代码 运行结果 分析&#xff1a; 折半插入排序 折半插入排序&#xff0c;折半插入排序是在直接插入的改进&#xff0c;通过折半查找得到插入位置&#xf…

java自定义类加载器来加载本地class文件,用demo来解析类加载的双亲委派机制、沙箱机制、打破双亲委派机制

1、首先将class文件放入指定本地目录下 2、编写自定义类加载器demo代码来加载class文件 /*** author WuSong* version 1.0* date 2022/12/7 12:07* description*/ public class MyClassLoaderTest {/*** 1&#xff1a;继承ClassLoader类* 2&#xff1a;重写findClass方法*/sta…

2023最新扫码连wifi-扫码挪车-聚合CPS返利多合一小程序源码

2023最新扫码连wifi-扫码挪车-聚合CPS返利多合一系统 系统特点: 目前已接入的 CPS 渠道: 充值:话费充值、电费充值、影视会员充值、会员卡券充值 本地团购:联联周边游 电商平台:京东、拼多多、唯品会、淘宝、抖音美团:外卖、闪购、酒店、到店、优选饿了么:外卖、商超 出行服务:…