vue3+ts+elementui-plus二次封装树形表格实现不同层级展开收起的功能

一、TableTreeLevel组件 

<template><div class='main'><div class="btns"><el-button type="primary" @click="expandLevel(1)">展开一级</el-button><el-button type="primary" @click="expandLevel(2)">展开二级</el-button><el-button type="primary" @click="expandLevel(3)">展开三级</el-button><el-button type="primary" @click="expandLevel(4)">展开四级</el-button><el-button type="warning" @click="putAwayLevel(0)">全部收起</el-button></div><div><el-table ref="multipleTableRef" :height="height" :default-expand-all="isExpend" :data="treeTableData"style="width: 100%; margin-bottom: 20px" row-key="id" border><el-table-column :width="item.width" :fixed="item.fixed" show-overflow-tooltip align="center"v-for="(item, i) in treeTableProps" :key="i" :label="item.label"><template #default="scope"><!-- 自定义插槽展示 --><slot v-if="item.slot" :name="item.prop" :scope="scope"></slot><!-- 非自定义处理(判空) --><span v-else-if="scope.row[item.prop] === '' || scope.row[item.prop] === null">--</span><!-- 非自定义处理(正常展示) --><span v-else>{{ scope.row[item.prop] }}</span></template></el-table-column></el-table></div></div>
</template><script lang="ts" setup>
import { ref, reactive, getCurrentInstance, onMounted, watch } from 'vue'
interface Props {// 属性名prop: string,// 属性标签label: string,// 是否固定(非必填)fixed?: boolean,// 行宽(非必填)width?: number,// 是否显示插槽(非必填)slot?: boolean,
}
const props = defineProps({/** 表格数据 */treeTableData: {type: Array,default: null,required: true},/** 表格属性 */treeTableProps: {type: Array<Props>,default: null,required: true},/** 是否默认全部展开 */isExpend: {type: Boolean,default: false,required: false},/** 表格高度 */height: {type: String,default: '60vh',required: false}
})
const multipleTableRef = ref() //获取table的ref
const expandNum = ref(0) //展开层级的数字/** 监听展开的层级数,如果当前选择的层级小于上一次选择的层级,就收起 */
watch(expandNum, (newValue, oldValue) => {if (newValue < oldValue) {putAwayLevel(newValue + 1)}
}, { deep: true })
/** 收起 */
const putAwayLevel = (num: number) => {let arr = ref(treeToArray(props.treeTableData))//将树形数据转为一维数组,方便一层遍历// 遍历收起当前层级arr.value.map((row: any) => {if (num == row.level) {multipleTableRef.value.toggleRowExpansion(row, false);}})// 下面递归调用目的是:假如你展开了4级,又点击展开2级,这时需要收起的是3级和4级,// 不然它只收起的2级,点开2级的时候,3级其实也是展开的.// 因此细节一点就是:展开2级,需要收起3、4级;展开1级,需要收起2、3、4级;展开3级,需要收起4级;if (++num < 4) {putAwayLevel(num)}
}
/** 展开 */
const expandLevel = (num: number) => {expandNum.value = numsetExpandKeys(props.treeTableData, num)
}/** 递归设置展开层级 */
const setExpandKeys = (dataList: any, level: number) => {// level为要展开的层级,先减一后使用,不然会多展开一级--level;// 当num大于0时,就对数组里面每一层依次进行展开if (level >= 0) {for (var i = 0; i < dataList.length; i++) {// toggleRowExpansion 用于可扩展的表格或树表格, 第二个参数为true则为展开该行,false为折叠。multipleTableRef.value.toggleRowExpansion(dataList[i], true);if (dataList[i].children) {setExpandKeys(dataList[i].children, level);}}}
}
/** 将树形数据转为一维数组的函数*/
const treeToArray = (arr: any) => {let data = JSON.parse(JSON.stringify(arr))let newData = ref([] as any)const callback = (item: any) => {(item.children || (item.children = [])).map((v: any) => {callback(v)})delete item.childrennewData.value.push(item)}data.map((v: any) => callback(v))return newData
}
onMounted(() => {
})</script>
<style scoped lang='less'>
.btns {margin-bottom: 20px;
}@media screen and (min-width: 200px) and (max-width: 1600px) {}@media screen and (min-width: 1601px) {}
</style>

二、使用

<!----------------------------BaseTableTreeLevel的使用-------------------------------><BaseTableTreeLevel :treeTableData="tableData" height="50vh" :treeTableProps="treeTableProps"></BaseTableTreeLevel>
<script lang='ts' setup>
import TableTree from '@/components/BaseTableTree/index.vue'
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
// 定义表格数据接口
interface dataList {id: numberdate: stringname: stringaddress: stringhasChildren?: booleanlevel: number,children?: dataList[]
}
// 定义表格头部属性名
const treeTableProps = [{ prop: 'date', label: '日期', width: 300, fixed: true, },{ prop: 'name', label: '名称', },{ prop: 'address', label: '地址', slot: true, },
]
// 定义表格假数据
const tableData: dataList[] = [{id: 1,date: '2016-05-04',name: '',address: 'No. 189, Grove St, Los Angeles',level: 1,children: [{id: 11,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,children: [{id: 111,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,},{id: 112,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,}]},{id: 12,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,},],},{id: 2,date: '2016-05-04',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 1,children: [{id: 21,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,children: [{id: 211,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,},{id: 212,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,}]},{id: 32,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,},],},{id: 3,date: '2016-05-01',name: '小明',level: 1,address: 'No. 189, Grove St, Los Angeles',children: [{id: 31,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,children: [{id: 311,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,},{id: 312,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 3,children: [{id: 3121,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 4,}, {id: 3122,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 4,},]}]},{id: 32,date: '2016-05-01',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 2,},],},{id: 4,date: '2016-05-03',name: '小明',address: 'No. 189, Grove St, Los Angeles',level: 1,},
]onMounted(() => {
})</script>

三、效果

我只定义了三层数据,就只演示展开了三层,还可以多层,自己设置即可 

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

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

相关文章

13年测试老鸟,接口性能测试总结整理,据说这是全网最全的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试按照不同…

【云原生系列】openstack搭建过程及使用

目录 搭建步骤 准备工作 正式部署OpenStack 安装的过程 安装组件如下 登录页面 进入首页 创建实例步骤 上传镜像 配置网络 服务器配置 dashboard配置 密钥配置免密登录 创建实例 绑定浮动ip 免密登录实例 搭建步骤 准备工作 1.关闭防火墙和网关 systemctl dis…

运维高级学习---MySQL备份恢复

数据库备份&#xff0c;数据库为school&#xff0c;素材如下 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) );创建sco…

【周赛第66期】题目、解答与疑义

目录 感想 判断题1.单选题1.2.&#xff08;有疑义&#xff09; 填空题1. 编程题1.路灯亮度题目题解答案 2.题目题解答案 感想 &#xff08;吐槽&#xff09; 在线IDE真不好用&#xff0c;不说不如CLion&#xff0c;抄一下leetcode的也好啊…… 希望支持比赛时实时看别人通过了…

MATLAB 创建神经网络模型的patternnet和newff函数区别

patternnet和newff都是在MATLAB中用于创建人工神经网络的函数&#xff0c;但它们有一些区别和适用场景。 网络类型&#xff1a; patternnet&#xff1a;用于创建多层感知器&#xff08;MLP&#xff09;类型的神经网络&#xff0c;MLP是一种前馈神经网络&#xff0c;由输入层、若…

Jupyter(CPP内核) || 如何在使用xeus-cling时添加第三方库

国内的搬运真是管杀不管埋。在CSDN上找了半天没有找到在xeus-cling添加第三方库的&#xff0c;最后还是只能自己到处去看英文文档。 先贴上英文文档的链接&#xff1a;Introduction — xeus-cling documentation 构建二进制文件时&#xff0c;通常在构建工具中指定包含目录和第…

抖音SEO源码开发指南:介绍如何开发抖音SEO源码的基本步骤和要点。

一、 抖音SEO源码开发指南&#xff1a; 确定目标&#xff1a;首先要明确开发抖音SEO源码的目标是什么&#xff0c;是提高搜索排名还是增加用户量等。根据不同的目标来制定开发策略和思路。 分析竞争&#xff1a;对于同类产品&#xff0c;要进行竞争分析&#xff0c;了解对手的…

threadLocal如何支持线程池获取

问题: ThreadLocal默认不支持子线程获取&#xff0c;而InheritableThreadLocal支持子线程获取threadLocal值&#xff0c;但是如果使用线程池&#xff0c;核心个数为1则子线程会获取到上一个threadLocal的值。 解决&#xff1a; 1.引入transmittable-thread-local jar <d…

k8s集群部署(使用kubeadm部署工具进行快速部署,相关对应版本为docker20.10.0+k8s1.23.0)

1. 安装要求 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#xff1a; 一台或多台机器&#xff0c;操作系统 CentOS7.x-86_x64硬件配置&#xff1a;2GB或更多RAM&#xff0c;2个CPU或更多CPU&#xff0c;硬盘20GB或更多可以访问外网&#xff0c;需要拉…

在Mac系统下搭建Selenium环境并驱动Chrome浏览器

本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器&#xff0c;虽然会有坑&#xff0c;但是我们可以凭借敏捷的身手躲过。下面就开始吧&#xff1a; 安装selenium 打开终端 ->pip安装&#xff08;安装命令&#xff1a;pip3 install selenium&#xff09; 安装浏览…

如何在 SwiftUI 中使用 Touch ID 和 Face ID?

1. 需要通过指纹&#xff0c;面容认证后才能打开 App 2. 添加配置 需要向 Info.plist 文件中添加一个配置&#xff0c;向用户说明为什么要访问 添加 Privacy - Face ID Usage Description 并为其赋予值 $(PRODUCT_NAME) need Touch Id or Face ID permission for app lock 3. …

LeetCode-0727

SQL50 基础 1633 select contest_id,Round(count(*) * 100/(select count(*) from Users),2) as percentage from Users cross join Registerusing(user_id)group by contest_idorder by count(*) desc,contest_id1211 select query_name , Round(avg(rating/position),2) as…

HTML不常用但是好用的标签

sub sup <p>这个文本包含 <sub>111</sub>文本。</p> <p>这个文本包含 <sup>上标</sup> 文本。</p>下标文本将会显示在当前文本流中字符高度的一半为基准线的下方&#xff0c;但是与当前文本流中文字的字体和字号都是一样的。…

Git竞合处理

Gitee新建一个代码仓库&#xff0c;clone到本地&#xff0c;模拟竞合的情况出现 这里仓库已经配好了ssh&#xff0c;所以没有添加账户绑定的步骤 clone到本地 模拟A同学Clone代码 git clone 项目地址新建一个文件&#xff0c;上传到仓库 push到仓库 代码仓库已经可以看到了…

HEVC网络适配层介绍

h265 的分层结构 分层结构的目的 ○ 网络类型多种多样&#xff0c;不同的网络环境具有不同的特性&#xff0c;压缩视频在其中进行传输必然会受到影响&#xff1b;比如不同网络的 MTU 有所不同&#xff1b; ○ 不同的应用场景对视频有不同的需求&#xff0c;视频业务会喜用不…

springboot快速整合腾讯云COS对象存储

1、导入相关依赖 <!--腾讯云COS--><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>3.0.1</version></dependency><dependency><groupId>com…

【矩特征】图像矩特征

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 cv2.moments() 矩特征 1. 正文 (1). 空间矩 零阶矩&#xff1a;m00一阶矩&#xff1a;m10,m01二阶矩&#xff1a;m20,m11,m02三阶矩&#xff1a;m30,m…

Python3 学习笔记 ~ 海象赋值表达式

Python 海象运算符_小嗷犬的博客-CSDN博客 myStr "abcdefghijgk"# n len(myStr) throw out exception when compling if n len(myStr) > 10 : print(f"{myStr} length: {n} is too long, expect less 10") else:print(f"{myStr} length: {n} is…

三维虚拟电子沙盘数字沙盘态势推演教程第12课

三维虚拟电子沙盘数字沙盘态势推演教程第12课 设置system.ini 如下内容 Server122.112.229.220 userGisTest Passwordchinamtouch.com 该数据库中只提供 成都市火车南站附近的数据请注意&#xff0c;104.0648,30.61658 SDK中自带了一套 导航系统&#xff0c;用的是比较详细的…

3. Spring 更简单的读取和存储对象(五大类注解 方法注解)

目录 1. 存储 Bean 对象 1.1 配置扫描路径 1.2 添加注解存储 Bean 对象 1.2.1 Controller&#xff08;控制器存储&#xff09; 1.2.2 Service&#xff08;服务存储&#xff09; 1.2.3 Repository&#xff08;仓库存储&#xff09; 1.2.4 Component&#xff08;组件存储&…