elementPlus实现动态表格单元格合并span-method方法总结

news2024/9/20 18:30:16

最近在做PC端需求的时候,需要把首列中相邻的同名称单元格合并。
我看了一下elementPlus官网中的table表格,span-method可以实现单元格合并。

我们先看一下官网的例子:

合并行或列

多行或多列共用一个数据时,可以合并行或列。

通过给 table 传入span-method方法可以实现合并行或列, 方法的参数是一个对象,里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组,第一个元素代表 rowspan,第二个元素代表 colspan。 也可以返回一个键名为 rowspan 和 colspan 的对象。
rowspan:合并几行
colspan:合并几列

<template>
  <div>
    <el-table
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%"
    >
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="Name" />
      <el-table-column prop="amount1" sortable label="Amount 1" />
      <el-table-column prop="amount2" sortable label="Amount 2" />
      <el-table-column prop="amount3" sortable label="Amount 3" />
    </el-table>

    <el-table
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px"
    >
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="Name" />
      <el-table-column prop="amount1" label="Amount 1" />
      <el-table-column prop="amount2" label="Amount 2" />
      <el-table-column prop="amount3" label="Amount 3" />
    </el-table>
  </div>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus'

interface User {
  id: string
  name: string
  amount1: string
  amount2: string
  amount3: number
}

interface SpanMethodProps {
  row: User
  column: TableColumnCtx<User>
  rowIndex: number
  columnIndex: number
}

const arraySpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  if (rowIndex % 2 === 0) {
    if (columnIndex === 0) {
      return [1, 2] // // 合并1行 合并2列
    } else if (columnIndex === 1) {
      return [0, 0]
    }
  }
}

const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  if (columnIndex === 0) {
    if (rowIndex % 2 === 0) {  // 2、4、6、8......
      return {
        rowspan: 2, // 合并2行
        colspan: 1, // 合并1列
      }
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
  }
}

const tableData: User[] = [
  {
    id: '12987122',
    name: 'Tom',
    amount1: '234',
    amount2: '3.2',
    amount3: 10,
  },
  {
    id: '12987123',
    name: 'Tom',
    amount1: '165',
    amount2: '4.43',
    amount3: 12,
  },
  {
    id: '12987124',
    name: 'Tom',
    amount1: '324',
    amount2: '1.9',
    amount3: 9,
  },
  {
    id: '12987125',
    name: 'Tom',
    amount1: '621',
    amount2: '2.2',
    amount3: 17,
  },
  {
    id: '12987126',
    name: 'Tom',
    amount1: '539',
    amount2: '4.1',
    amount3: 15,
  },
]
</script>

效果如下:
在这里插入图片描述
好了,官网例子看过,来看看我在实际项目中是怎么应用的。
需要处理的数据如下:

let data = [
            {
                firstName: '基本证照',
                code: '001',
                secondName: '营业执照',
                sort: '30',
                fileList: [
                    {
                        id: '1',
                        name: '营业执照照片'
                    }
                ]
            },
            {
                firstName: '基本证照',
                code: '002',
                secondName: '身份证照',
                sort: '40',
                fileList: [
                    {
                        id: '2',
                        name: '身份证照照片'
                    }
                ]
            },
            {
                firstName: '现场照片',
                code: '003',
                secondName: '公司前台照',
                sort: '50',
                fileList: [
                    {
                        id: '3',
                        name: '公司前台照照片'
                    }
                ]
            },
            {
                firstName: '现场照片',
                code: '004',
                secondName: '公司工位照',
                sort: '60',
                fileList: [
                    {
                        id: '4',
                        name: '公司工位照照片'
                    }
                ]
            },
            {
                firstName: '经营证明',
                code: '005',
                secondName: '工厂生产照',
                sort: '70',
                fileList: [
                    {
                        id: '5',
                        name: '工厂生产照照片'
                    }
                ]
            }
        ]

需要展示的效果是:
首列中只有三行(基本证照、现场照片、经营证明)
也就是说 基本证照、现场照片这个两个首列需要合并两行

封装的函数如下,函数中都是注释,对函数中的定义和字段做了详细的说明。

        // 合并单元格规则(data为表格数据,cateName为合并字段的名称)这个函数的作用是对首列中的行进行合并
        function objSpanMethod({ row, column, rowIndex, columnIndex }, data, cateName) {
            // 非首列的数据都返回,不往下进行
            if (columnIndex !== 0) {
                return
            }
            let arrLength = [] // 存放secondName对应的数据数组长度
            let cateRows = [] // 存放起始合并行以及合并行数
            data.reduce((preValue, curValue, index, array) => {
                if (index == 0 || preValue[cateName] != curValue[cateName]) {
                    arrLength.push(1)
                } else {
                    arrLength[arrLength - 1]++
                }
                return curValue
            }, data[0])

            // 获取存放起始合并行以及合并行数
            arrLength.reduce((pre, cur, index, value) => { // pre指的是上一次计算过后的prev + cur这个值
                cateRows.push({ rowIndex: prev, rowspan: cur }); // rowIndex指的是从第几行开始合并,rowspan指的是合并几行
                return prev + cur
            }, 0)

            let intRowSpan = 0;
            for (let i = 0; i < arrLength.length; i++) {
                if (cateRows[i].rowIndex == rowIndex) {
                    intRowSpan = cateRows[i].rowspan;
                    break;
                }
            }
            return {
                // 当渲染执行到某一行的首列时,或者执行到首列时,对其中的行进行渲染时,例如渲染到第四行时,发现rowspan为3时,
                // 那就是首列中从第四行开始合并,合并3行,四、五、六这三行合并为一行。
                rowspan: intRowSpan,
                colspan: intRowSpan == 0 ? 0 : 1  // 如果不合并行,就返回0,说白了就不合并
            }
        }

具体的使用请看以下完整的代码:

<template>
  <div class="table">
    <el-table
      :data="data"
      :span-method="(param) => objSpanMethod(param, data, 'firstName')"
    >
      <el-table-colum prop="firstName" label="资料分类" width="150" />
      <el-table-colum prop="secondName" label="资料名称" />
      <el-table-colum prop="fileList" label="已上传资料">
        <template #default="{ row }">
          <p v-for="(item,index)" in row.fileList :key="item?.name + index">
            <span>
              {{ item?.name }}
            </span>
          </p>
        </template>
      </el-table-colum>
    </el-table>
  </div>
</template>

<script setup>
// data是接口请求回来的数据
// 数据如下:
let data = [
  {
    firstName: "基本证照",
    code: "001",
    secondName: "营业执照",
    sort: "30",
    fileList: [
      {
        id: "1",
        name: "营业执照照片",
      },
    ],
  },
  {
    firstName: "基本证照",
    code: "002",
    secondName: "身份证照",
    sort: "40",
    fileList: [
      {
        id: "2",
        name: "身份证照照片",
      },
    ],
  },
  {
    firstName: "现场照片",
    code: "003",
    secondName: "公司前台照",
    sort: "50",
    fileList: [
      {
        id: "3",
        name: "公司前台照照片",
      },
    ],
  },
  {
    firstName: "现场照片",
    code: "004",
    secondName: "公司工位照",
    sort: "60",
    fileList: [
      {
        id: "4",
        name: "公司工位照照片",
      },
    ],
  },
  {
    firstName: "经营证明",
    code: "005",
    secondName: "工厂生产照",
    sort: "70",
    fileList: [
      {
        id: "5",
        name: "工厂生产照照片",
      },
    ],
  },
];

// 合并单元格规则(data为表格数据,cateName为合并字段的名称)这个函数的作用是对首列中的行进行合并
function objSpanMethod({ row, column, rowIndex, columnIndex }, data, cateName) {
  // 非首列的数据都返回,不往下进行
  if (columnIndex !== 0) {
    return;
  }
  let arrLength = []; // 存放secondName对应的数据数组长度
  let cateRows = []; // 存放起始合并行以及合并行数
  data.reduce((preValue, curValue, index, array) => {
    if (index == 0 || preValue[cateName] != curValue[cateName]) {
      arrLength.push(1);
    } else {
      arrLength[arrLength - 1]++;
    }
    return curValue;
  }, data[0]);

  // 获取存放起始合并行以及合并行数
  arrLength.reduce((pre, cur, index, value) => {
    // pre指的是上一次计算过后的prev + cur这个值
    cateRows.push({ rowIndex: prev, rowspan: cur }); // rowIndex指的是从第几行开始合并,rowspan指的是合并几行
    return prev + cur;
  }, 0);

  let intRowSpan = 0;
  for (let i = 0; i < arrLength.length; i++) {
    if (cateRows[i].rowIndex == rowIndex) {
      intRowSpan = cateRows[i].rowspan;
      break;
    }
  }
  return {
    // 当渲染执行到某一行的首列时,或者执行到首列时,对其中的行进行渲染时,例如渲染到第四行时,发现rowspan为3时,
    // 那就是首列中从第四行开始合并,合并3行,四、五、六这三行合并为一行。
    rowspan: intRowSpan,
    colspan: intRowSpan == 0 ? 0 : 1, // 如果不合并行,就返回0,说白了就不合并
  };
}
</script>

<style>
</style>

这样就完全实现了首列中行的合并。总结这些呢,主要是记录下rowspan:合并几行
colspan:合并几列
这个规则,还是就是合并行中对于数据的处理。

好记性不如烂笔头,虽然当时明白的很好,但是还是总结记录下来最好。

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

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

相关文章

远程手机搭建Termux环境,并通过ssh连接Termux

背景 Termux只能通过鼠标点击&#xff0c;无法使用电脑键盘&#xff0c;输入速度很慢&#xff0c;你想通过ssh 连接Termux&#xff0c;获得友好体验搞了个云手机&#xff0c;想像普通手机那样充当服务器想把自己的手机公开到局域网中供同事调试想把自己的模拟器公开到局域网中…

51 -25 Scene as Occupancy 3D占用作为场景表示 论文精读

本文阅读的文章是Scene as Occupancy&#xff0c;介绍了一种将物体表示为3D occupancy的新方法&#xff0c;以描述三维场景&#xff0c;并用于检测、分割和规划。 文章提出了OccNet和OpenOcc两个核心概念。 OccNet 3D占用网络是一种以多视图视觉为中心的方法&#xff0c;通过…

ArcGIS的UTM与高斯-克吕格投影分带要点总结

UTM&#xff08;通用横轴墨卡托投影、等角横轴割椭圆柱投影&#xff09;投影分带投影要点&#xff1a; 1&#xff09;UTM投影采用6度分带 2&#xff09;可根据公式计算&#xff0c;带数&#xff08;经度整数位/6&#xff09;的整数部分31 3&#xff09;北半球地区&#xff0…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(9)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;8&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备&…

【iOS分类、关联对象】如何使用关联对象给分类实现一个weak的属性

如何使用关联对象给分类实现一个weak的属性 通过关联对象objc_setAssociatedObject中的策略policy可知&#xff0c;并不支持使用weak修饰对象属性&#xff1a; typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {OBJC_ASSOCIATION_ASSIGN 0, //assignOBJC_ASSOCIATION…

Java基于微信小程序的医院挂号系统

文章目录 1 简介2 技术栈3 系统目标3.2 系统功能需求分析3.2.1 功能需求分析 4 系统模块设计4.1 数据库模块设计 5 系统的实现5.1 微信小程序个人中心5.2 科**室内容查看的实现**5.3 预约挂号的实现5.4 后台管理界面实现5.5 医生预约管理5.6 医生信息管理 参考文献7 推荐阅读8 …

Cocos creator 3.x 刚体组件碰撞无效

Cocos creator 3.x 刚体组件碰撞无效 问题描述&#xff1a;只有一个circleCollider2D时&#xff0c;可以在碰撞时正确输出结果&#xff0c;但是当我在外围加了一个circle之后&#xff0c;期望character进入圆圈范围时就触发方法&#xff0c;此时原代码失效 import { _decorat…

java SpringBoot2.7整合Elasticsearch(ES)7 进行文档增删查改

首先 我们在 ES中加一个 books 索引 且带有IK分词器的索引 首先 pom.xml导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>applicatio…

Asp .Net Core 集成 NLog

简介 NLog是一个基于.NET平台编写的日志记录类库&#xff0c;它可以在应用程序中添加跟踪调试代码&#xff0c;以便在开发、测试和生产环境中对程序进行监控和故障排除。NLog具有简单、灵活和易于配置的特点&#xff0c;支持在任何一种.NET语言中输出带有上下文的调试诊断信息…

正确入市时机3秒抓住,WeTrade众汇无偿实例分享

在上篇文章中&#xff0c;WeTrade众汇无偿分享如何3秒抓住正确入市的时机&#xff0c;今天让我们通过一个例子来验证这个策略的正确性。 对于突破策略&#xff0c;WeTrade众汇用了同样的图表来演示挤压交易。蓝色箭头表示变窄的区域&#xff0c;红色箭头表示烛台穿过下层。当它…

代码随想录 Leetcode46. 全排列

题目&#xff1a; 代码&#xff08;首刷自解 2024年2月6日&#xff09;&#xff1a; class Solution { private:vector<vector<int>> res;vector<int> path; public:void backtracking(vector<int>& nums, int depth, vector<bool>& us…

三月济南举办2024第八届生物饲料高质量发展论坛

饲料工业发展空间大&#xff0c;产量持续增长&#xff0c;品质与质量也在不断提高&#xff0c;饲料工业是支撑现代畜牧水产养殖业发展的基础产业&#xff0c;是关系到城乡居民动物性食品供应的民生产业。“十四五”时期是我国由全面建设小康社会向基本实现社会主义现代化迈进的…

Python中的包模块引用成员的方法

在Python中&#xff0c;包&#xff08;package&#xff09;和模块&#xff08;module&#xff09;是组织和管理代码的重要方式。将代码分成不同的模块或包可以更好地组织代码结构&#xff0c;使代码更易于维护和管理。说的通俗点&#xff0c;就是将代码整理成一块一块&#xff…

计算机服务器中了mkp勒索病毒如何解密,mkp勒索病毒解密流程

随着网络技术的不断发展与应用&#xff0c;越来越多的企业走向数字化办公模式&#xff0c;计算机极大地方便了企业的正常生产运营&#xff0c;但网络威胁的手段也不断增加。近期&#xff0c;云天数据恢复接到很多企业的求助&#xff0c;企业的计算机服务器遭到了mkp勒索病毒攻击…

js中的事件模型详解

文章目录 一、事件与事件流二、事件模型原始事件模型标准事件模型IE事件模型 一、事件与事件流 javascript中的事件&#xff0c;可以理解就是在HTML文档或者浏览器中发生的一种交互操作&#xff0c;使得网页具备互动性&#xff0c; 常见的有加载事件、鼠标事件、自定义事件等 …

红外避障模块

目录 一、模块原理 二、模块使用说明 三、材料准备 四、代码 五、实验效果 实验效果 自动灯效果&#xff1a; 避障模块-CSDN直播 一、模块原理 红外避障模块利用光反射原理&#xff0c;模块前端拥有一个红外发射管和一个红外接收管。模块通电后红外发射管向前方不断发射…

ES监控方法以及核心指标

文章目录 1. 监控指标采集1.1 部署elasticsearch_exporter1.2 prometheus采集elasticsearch_exporter的暴露指标1.3 promethues配置告警规则或者配置grafana大盘 2. 核心告警指标2.1 es核心指标2.2 es容量模型建议 3. 参考文章 探讨es的监控数据采集方式以及需要关注的核心指标…

Linux--文件

文件的基本信息 文件是计算机系统中存储数据的一种单位。 它可以是文本、图像、音频、视频等信息的载体。文件通常以特定的格式和拓展名来表示其内容和类型。 在计算机系统中&#xff0c;文件使用文件名来唯一标识和访问。文件可以被创建、读取、写入、复制、移动、删除等操作…

《Java程序设计》实验报告(二)之面向对象编程基础

实验内容及步骤&#xff1a; 编写不带构造函数的类并测试。&#xff08;学生类、圆类&#xff09;&#xff08;1&#xff09;代码&#xff1a; class Student { String name"张三"; int age20; String sex"男";//gender String getName(){…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之RichText组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之RichText组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、RichText组件 鸿蒙&#xff08;HarmonyOS&#xff09;富文本组件&#xff0c;…