vue3.2 + vxe-table4.x 实现多层级结构的 合并、 展开、收起 功能

server/2025/3/1 22:19:42/
javascript"><template><div style="padding: 20px"><vxe-table border :data="list" :height="800" :span-method="rowspanMethod"><vxe-column title="一级类目" field="category1"><template #default="{ row }"><a-space><span>{{ row.category1 }}</span><a-button @click="toggleCategoryExpand(row, '1')">{{ showText(row, '1') ? '收起' : '展开' }}</a-button></a-space></template></vxe-column><vxe-column title="二级类目" field="category2"><template #default="{ row }"><a-space><span>{{ row.category2 }}</span><a-buttonv-if="showText(row, '1')"@click="toggleCategoryExpand(row, '2')">{{ showText(row, '2') ? '收起' : '展开' }}</a-button></a-space></template></vxe-column><vxe-column title="三级类目" field="category3"></vxe-column><vxe-column title="报告金额" field="amount"></vxe-column><vxe-column title="合计" field="total"></vxe-column></vxe-table></div>
</template><script>
import { defineComponent, ref } from 'vue'
import XEUtils from 'xe-utils'export default defineComponent({setup() {const flattenedData = [{id: '0',category: '人工成本',parentId: null},{id: '0-0',parentId: '0',category: '人工成本0-0'},{id: '0-0-0',parentId: '0-0',category: '人工成本0-0-0'},{id: '0-0-1',parentId: '0-0',category: '人工成本0-0-1'},{id: '0-1',parentId: '0',category: '人工成本0-1'},{id: '0-1-0',parentId: '0-1',category: '人工成本0-1-0'},{id: '0-1-1',parentId: '0-1',category: '人工成本0-1-1'}]const treeData = XEUtils.toArrayTree(flattenedData)const treeDataTemp = JSON.parse(JSON.stringify(treeData))const renderTreeData = ref(treeDataTemp)const list = ref([])// 工具方法const toColTreeData = (treeData) => {const options = { children: 'children' }const list = []const keyMap = {}XEUtils.eachTree(treeData,(item, index, result, paths, parent) => {keyMap[item.id] = itemitem.keys = parent ? parent.keys.concat([item.id]) : [item.id]if (!item.children || !item.children.length) {const row = {}item.keys.forEach((key, index) => {const level = index + 1const obj = keyMap[key]row[`category${level}`] = obj.categoryrow[`id${level}`] = obj.id})list.push(row)}},options)return list}const rowspanMethod = ({ row, _rowIndex, column, visibleData }) => {const fields = ['category1', 'category2']const cellValue = row[column.field]if (cellValue && fields.includes(column.field)) {const prevRow = visibleData[_rowIndex - 1]let nextRow = visibleData[_rowIndex + 1]if (prevRow && prevRow[column.field] === cellValue) {return { rowspan: 0, colspan: 0 }} else {let countRowspan = 1while (nextRow && nextRow[column.field] === cellValue) {nextRow = visibleData[++countRowspan + _rowIndex]}if (countRowspan > 1) {return { rowspan: countRowspan, colspan: 1 }}}}}renderTreeData.value.forEach((item) => {if (item.children.length) {item.children = []}})list.value = toColTreeData(renderTreeData.value)const toggleCategoryExpand = (row, level) => {if (level === '1') {toggleLevelOne(row)}if (level === '2') {toggleLevelTwo(row)}}const toggleLevelOne = (row) => {const { id1 } = rowconst item = renderTreeData.value.find((item) => item.id === id1)if (item.children.length) {item.children = []} else {const a = treeData.find((item) => item.id === id1)item.children = JSON.parse(JSON.stringify(a.children))item.children.forEach((child) => {child.children = []})}list.value = toColTreeData(renderTreeData.value)}const toggleLevelTwo = (row) => {const { id1, id2 } = rowconst item1 = renderTreeData.value.find((item) => item.id === id1)const item2 = item1.children.find((item) => item.id === id2)if (item2.children.length) {item2.children = []} else {const a1 = treeData.find((item) => item.id === id1)const a2 = a1.children.find((item) => item.id === id2)item2.children = a2.children}list.value = toColTreeData(renderTreeData.value)}const showText = (row, level) => {const { id1, id2 } = rowif (level === '1') {const item = renderTreeData.value.find((item) => item.id === id1)if (item) {return item.children.length}return false}if (level === '2') {const item1 = renderTreeData.value.find((item) => item.id === id1)const item2 = item1.children.find((item) => item.id === id2)if (item2) {return item2.children.length}return false}}return {rowspanMethod,toggleCategoryExpand,list,showText}}
})
</script>

在这里插入图片描述


http://www.ppmy.cn/server/171646.html

相关文章

2.部署kafka:9092

官方文档&#xff1a;http://kafka.apache.org/documentation.html (虽然kafka中集成了zookeeper,但还是建议使用独立的zk集群) Kafka3台集群搭建环境&#xff1a; 操作系统: centos7 防火墙&#xff1a;全关 3台zookeeper集群内的机器&#xff0c;1台logstash 软件版本: …

Android 8.0 (API 26) 对广播机制做了哪些变化

大部分隐式广播无法通过静态注册接收&#xff0c;除了以下白名单广播&#xff1a; ACTION_BOOT_COMPLETED ACTION_TIMEZONE_CHANGED ACTION_LOCALE_CHANGED ACTION_MY_PACKAGE_REPLACED ACTION_PACKAGE_ADDED ACTION_PACKAGE_REMOVED 需要以动态注册方案替换&#xff1a; cl…

【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus

文章目录 一、什么是 Mybatis Plus 特性 二、Spring Boot 3.0 集成 Mybatis Plus三、Mybatis Plus 查询示例 1、普通查询2、分页查询 参考 一、什么是 Mybatis Plus MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只…

docker通用技术介绍

docker通用技术介绍 1.docker介绍 1.1 基本概念 docker是一个开源的容器化平台&#xff0c;用于快速构建、打包、部署和运行应用程序。它通过容器化技术将应用及其依赖环境&#xff08;如代码、库、系统工具等&#xff09;打包成一个标准化、轻量级的独立单元&#xff0c;实…

使用vscode导出Markdown的PDF无法显示数学公式的问题

我的硬件环境是M2的MacBook air&#xff0c;在vscode中使用了Markdown PDF来导出md文件对应的PDF。但不管导出html还是PDF文件&#xff0c;数学公式都是显示的源代码。 我看了许多教程&#xff0c;给的是这个方法&#xff1a;在md文件对应的html文件中加上以下代码&#xff1a…

非关系型数据库和关系型数据库的区别

非关系型数据库&#xff08;NoSQL&#xff09;和关系型数据库&#xff08;SQL&#xff09;的主要区别体现在以下几个方面&#xff1a; 数据模型&#xff1a; 关系型数据库&#xff08;SQL&#xff09;&#xff1a;数据以表格形式存储&#xff0c;数据行和列组成&#xff0c;每个…

多线程3:MFC中用户界面线程的相关操作

文章目录 前言一、工作线程与界面线程的区别1.在子线程中创建模态对话框2.在子线程中创建非模态对话框二、界面线程1.界面线程的创建总结前言 多线程3:MFC中用户界面线程的相关操作。 一、工作线程与界面线程的区别 工作线程与界面线程主要是针对MFC中的线程来说的。默认情况…

ClkLog里程碑:荣获2024上海开源技术应用创新竞赛三等奖

2024年10月&#xff0c;ClkLog团队参加了由上海计算机软件技术开发中心、上海开源信息技术协会联合承办的2024上海数智融合“智慧工匠”选树、“领军先锋”评选活动——开源技术应用创新竞赛。我们不仅成功晋级决赛&#xff0c;还荣获了三等奖&#xff01;这一成就不仅是对ClkL…