Element-UI实现复杂table表格结构

news2024/9/24 15:22:08

Element-UI组件el-table用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。

将使用到以下两项,来完成今天demo演示:

  1. 多级表头:数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。

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

官方文档地址:https://element.eleme.cn/#/zh-CN/component/table

需要实现的表格如下图:

一、安装element-ui

使用npm进行安装:

npm i element-ui -S

二、表头实现

这里表头实现比较简单,代码如下:

<template>
  <div>
    <el-table :data="tableStudentData" :span-method="reconstructionStuCell" style="width: 100%">
      <el-table-column type="index" label="序号" width="50"></el-table-column>
      <el-table-column prop="name" label="姓名" width="80"></el-table-column>
      <el-table-column label="科目信息">
        <el-table-column prop="courseName" label="科目" width="80"></el-table-column>
        <el-table-column prop="date" label="日期" width="80"></el-table-column>
        <el-table-column prop="timeStr" label="考试时间" width="100"></el-table-column>
      </el-table-column>
      <el-table-column label="成绩信息">
        <el-table-column prop="score" label="成绩" width="60"></el-table-column>
        <el-table-column prop="scoreTotal" label="总分" width="60"></el-table-column>
        <el-table-column prop="total" label="满分" width="60"></el-table-column>
        <el-table-column prop="totalAll" label="满分总分" width="100">
          <template slot-scope="scope">
            <span v-if="scope.row.totalAll">{{scope.row.totalAll}} (及格率:{{parseInt(scope.row.scoreTotal/scope.row.totalAll*100)}}%)</span>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
    
  </div>
</template>

<script>
  export default {
    data(){
      return {
        tableData: [],
        tableStudentData: []
      }
    },
    created() {
 
    },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

<style lang="scss">

</style>

此时表头效果已形成,如下图:

三、数据渲染

数据渲染这里较为复杂,这里为方便大家理解,进行逐步拆解叙述。如有更好方法,也欢迎大家指点。

3.1 模拟数据

如上图,在element-table目录中,新建data.js文件,用于存储模拟数据,代码如下:

export const studentData = [
  {name: "李四", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 90, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 70, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 100, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 72, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 95, total: 150},
  ]},
  {name: "王五", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 85, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 60, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 90, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 68, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 75, total: 150},
  ]},
  {name: "小美", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 120, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 85, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 120, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 80, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 130, total: 150},
  ]}
];

页面中引入模拟数据,并赋值给表格的变量,代码如下:

<script>
  import { studentData } from './data.js'
  export default {
    data(){
      return {
        tableStudentData: studentData
      }
    },
    created() { },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

此时表格中可以正常渲染出部分数据了,效果图如下:

3.2 数据处理

如上图会发现,科目和成绩相关信息,未显示出来。这里需要对数据进行处理下,将所有科目信息调整到 和姓名字段为同一行数据中。需要做以下几步:

  1. 将subject二级数据全部移至name同级的同一行数据中。

  1. 将name字段原数据移至subject的第一行数据中;item和sub进行合并。

  1. 无subject子项数据的,保持原数据输出。

在data.js中,添加重构数据reconstructionStuData()函数,代码如下:

/**
 * 重构学生数据 并返回
 */
export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&&item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ }, item, sub);
        }
        //其他行数据无须添加 姓名字段信息(第一行数据会合并到结束位置,填充后也会被覆盖)
        else{
          subData = Object.assign({ }, sub);
        }
        //if end
        tmpData.push( subData );
      });
    }
    //subject无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ }, item)
      );
    }
  });

  return tmpData;
}

引入reconstructionStuData()函数,代码如下:

<script>
  import { reconstructionStuData, studentData } from './data.js'
  export default {
    data(){
      return {
        tableStudentData: studentData
      }
    },
    created() {
      this.tableStudentData = reconstructionStuData(studentData);
    },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

此时表格效果图如下:

3.4 图解

如上图,

  • 列(姓名)位于列的第1位置(起始从0开始,所以序号为第0位置),往下合并subject数组长度位置即可。

  • 列(总分)位于列的第6位置,往下合并subject数组长度位置即可。

  • 列(满分总分)位于列的第8位置,往下合并subject数组长度位置即可。

这是我们会发现,methods中定义的reconstructionStuCell()函数还未使用,通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。

这里我们添加以下逻辑,在每行数据中添加姓名、总分,满分总分对应columnIndex1、columnIndex6、columnIndex8字段,用来存储需要返回的colspan和rowspan数据,代码如下:

reconstructionStuCell({ row, column, rowIndex, columnIndex }){
    let column1Data = row['columnIndex1'];
    let column6Data = row['columnIndex6'];
    let column8Data = row['columnIndex8'];
    
    //判断条件满足情况下,返回对应的rowspan和colspan数据
    if(
      (column1Data&&column1Data.columnIndex==columnIndex) ||      //姓名组合并
      (column6Data&&column6Data.columnIndex==columnIndex) ||      //总分组合并
      column8Data&&column8Data.columnIndex==columnIndex           //满分总分组合并
    ){
      return {
        rowspan: column1Data.rowspan,
        colspan: column1Data.colspan
      }
    }
    //if end
  }

以上代码添加后,发现表格并无任何变化,这是因为重构数据函数中,还未添加对应的columnIndex1、columnIndex6、columnIndex8字段。

3.5 合并列 - 姓名

首先,我们来合并(姓名)这列数据,将每行数据中添加columnIndex1,子属性变量columnIndex表示合并对应的列位置。

subject有子项数据除第一行数据,后面所有rowspan和colspan为0,表示无需渲染该单元格,第一行数据会向下合并并渲染,填补空缺位置。

subject无子项数据rowspan和colspan为1,保留原位置渲染。如为0则当前单元格不被渲染,表格会错乱。

代码如下:

export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&&item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: item.subject.length, colspan: 1 } }, item, sub);
        }
        //其他行数据无须添加 姓名字段信息(第一行数据会合并到结束位置,填充后也会被覆盖)
        else{
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 0, colspan: 0 } }, sub);
        }
        //if end
        tmpData.push( subData );
      });
    }
    //无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 1, colspan: 1 } }, item)
      );
    }
  });

  return tmpData;
}

此时大家看到表格的(姓名)列,已合并到对应长度,效果图如下:

3.6 合并列 - 总分和满分总分

总分和满分总分合并部分,和(姓名)列同理,但多出一步则需计算出对应科目的总分 和 所有科目的满分总分。

增加第6列和第8列合并数据columnIndex6和columnIndex8,并新增scoreTotal和totalAll分别保存总分和满分总分结果。

代码如下:

export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&&item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: item.subject.length, colspan: 1 } }, item, sub);

          //计算总分
          subData['scoreTotal'] = item.subject.reduce((total, value) => {
            return total + value.score;
          }, 0);
          subData['columnIndex6'] = { columnIndex: 6, rowspan: item.subject.length, colspan: 1 };
          //计算满分总分
          subData['totalAll'] = item.subject.reduce((total, value) => {
            return total + value.total;
          }, 0);
          subData['columnIndex8'] = { columnIndex: 8, rowspan: item.subject.length, colspan: 1 };
        }
        //其他行数据无须添加 姓名字段信息(第一行数据会合并到结束位置,填充后也会被覆盖)
        else{
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 0, colspan: 0 } }, sub);

          //总分和满分总分 被合并部分单元格填写为0
          subData['columnIndex6'] = { columnIndex: 6, rowspan: 0, colspan: 0 };
          subData['columnIndex8'] = { columnIndex: 8, rowspan: 0, colspan: 0 };
        }
        //if end
        tmpData.push( subData );
      });
    }
    //无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 1, colspan: 1 } }, item)
      );
    }
  });

  return tmpData;
}

此时,咱们需要的表格就被渲染出来了,如下图:

这里reconstructionStuData()函数处理能力还是相对不足,只能处理特定的表格合并。希望对大家有所帮助,仅供大家参考!

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

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

相关文章

Web3中文|Web3CN加速器第二期「Web3项目征集」火热报名

Web3CN加速器第二期「Web3项目征集」火热征集中&#xff0c;本次征集活动是由Web3CN加速器联合专业web3媒体Web3CN、VC机构Tiger VC DAO核心发起&#xff0c;数百家加密VC机构、加密社区等联合发起的&#xff0c;为早期Web3创新创业项目提供加速服务。如果你正在进行web3相关的…

VC常见问题(.obj : error LNK2019、fatal error C1083、编译64位Detours)

VC常用问题VC常见问题*.obj : error LNK2019: 无法解析的外部符号 __imp_FindWindow ,该符号在函数 YAWindows环境下用nmake编译常见问题fatal error C1083: 无法打开包括文件:“excpt.h”vs2012编译64位Detours&#xff08;其他vs版本同理&#xff09;vs项目设置选项编译使用了…

Java基础面试题(三)

Java基础面试题 一、JavaWeb专题 1.HTTP响应码有哪些 1、1xx&#xff08;临时响应&#xff09; 2、2xx&#xff08;成功&#xff09; 3、3xx&#xff08;重定向&#xff09;&#xff1a;表示要完成请求需要进一步操作 4、4xx&#xff08;错误&#xff09;&#xff1a;表示请…

Nuxt实战教程基础-Day01

Nuxt实战教程基础-Day01Nuxt是什么&#xff1f;Nuxt.js框架是如何运作的&#xff1f;Nuxt特性流程图服务端渲染(通过 SSR)单页应用程序 (SPA)静态化 (预渲染)Nuxt优缺点优点缺点安装运行项目总结前言&#xff1a;本教程基于Nuxt2&#xff0c;作为教程的第一天&#xff0c;我们先…

BUUCTF-[RoarCTF2019]polyre

题目下载&#xff1a;下载 这道题目是一个关于控制流平坦化和虚假流程。 首先了解一下控制流平坦化&#xff1a;利用符号执行去除控制流平坦化 - 博客 - 腾讯安全应急响应中心https://www.cnblogs.com/zhwer/p/14081454.htmlbuuctf RoarCTF2019 polyre writeup - 『脱壳破解区…

单点登录的几种实现方式探讨

单点登录&#xff08;Single Sign On&#xff09;&#xff0c;简称为 SSO&#xff0c;是解决企业内部的一系列产品登录问题的方案。SSO 的定义是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统&#xff0c;用于减少用户重复的登录操作&#…

PyTorch的自动微分(autograd)

PyTorch的自动微分(autograd) 计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量、矩阵、张量 边表示运算&#xff0c;如加减乘除卷积等 用计算…

共话开源 | 开放原子开源基金会专题调研openKylin社区!

3月8日&#xff0c;开放原子开源基金会秘书长冯冠霖、运营部部长李博、业务发展部部长朱其罡、研发部副部长周济一行莅临openKylin社区调研交流&#xff0c;麒麟软件高级副总经理韩乃平、副总裁董军平、终端研发部副总经理陆展、产品规划部经理常亚武、市场与政府事务部高级经理…

力扣sql简单篇练习(二十五)

力扣sql简单篇练习(二十五) 1 无效的推文 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT tweet_id FROM Tweets WHERE CHAR_LENGTH(content)>151.3 运行截图 2 求关注者的数量 2.1 基本题目内…

【Linux实战篇】二、在Linux上部署各类软件

一、实战章节&#xff1a;在Linux上部署各类软件 二、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统&#xff08;后续简称MySQL&#xff09;&#xff0c;是一款知名的数据库系统&#xff0c;其特点是&#xff1a;轻量、简单、功能丰富。 MySQL数据库可谓是…

在矩池云运行 Stable Diffusion web UI,使用v1.5模型和 ControlNet 插件

今天给大家介绍下如何在矩池云使用 Stable Diffusion web UI v1.5 模型和 Stable Diffusion ControlNet 插件。 租用机器 租用机器需要选择内存大于8G的机器&#xff0c;比如 A2000&#xff0c;不然 Stable Diffusion web UI 启动加载模型会失败。&#xff08;Killed 内存不足…

近20个省市加快房屋网签备案,君子签电子签章助推掌上办理

2020年以来&#xff0c;上海、北京、深圳、长沙、武汉、杭州、山东、郑州、西安、佛山、青岛、江门、昆明、韶关、南京、石家庄等全国近20个省市纷纷响应住建部政策要求&#xff0c;鼓励使用电子签名、电子签章等技术加快推动商品房、二手房或租赁房交易合同网签备案&#xff0…

是面试官放水,还是公司实在是太缺人?这都没挂,字节原来这么容易进...

字节是大企业&#xff0c;是不是很难进去啊&#xff1f;” “在华为做软件测试&#xff0c;能得到很好的发展吗&#xff1f; 一进去就有10K&#xff0c;其实也没有想的那么难” 直到现在&#xff0c;心情都还是无比激动&#xff01; 本人211非科班&#xff0c;之前在字节和腾讯…

UEFI开发探索101 – PCD探究(helloworld中的使用)

2 如何使用PCD PCD可以使用于UEFI存在的大部分时间&#xff0c;除了在SEC阶段、早期的PEI和DXE阶段&#xff0c;基本都可以访问。在使用前&#xff0c;我们需要搞清楚PCD的结构和类型。 2.1 PCD的类型 PCD变量的格式有点像结构体&#xff1a; TokenSpaceGuidCName.PcdCName …

【SpringCloud】SpringCloud教程之Gateway实战

目录前言SpringCloud Gatewy网关一.网关功能和工作原理二.网关的类型三.搭建网关四.路由断言工厂(Route Predicate Factory)五.路由过滤器(属于GatewayFilter)六.DefaultFilter过滤器(属于GatewayFilter)七.全局过滤器(GlobalFilter)八.过滤器执行顺序九.Gateway解决跨域问题前…

什么蓝牙耳机适合长时间佩戴?长久佩戴舒适的蓝牙耳机

因为我每天使用蓝牙耳机时间比较长&#xff0c;而且在上下班的路上经常会听听音乐&#xff0c;所以还是非常在意耳机的舒适度&#xff0c;有些耳机压迫感很明显&#xff0c;用久了感觉很不舒服&#xff0c;近期就购入了许多蓝牙耳机&#xff0c;终于整理出了一起佩戴舒适度高的…

vue+echarts.js 实现中国地图——根据数值表示省份的深浅——技能提升

最近在写后台管理系统&#xff0c;遇到一个需求就是 中国地图根据数值 展示深浅颜色。 效果图如下&#xff1a; 直接上代码&#xff1a; 1.html部分 <div id"Map"></div>2.css部分——一定要设置尺寸 #Map {width: 100%;height: 400px; }3.js部分 …

【立体匹配论文阅读】AANet: Adaptive Aggregation Network for Efficient Stereo Matching

Authors: Haofei Xu, Juyong Zhang Link: https://arxiv.org/abs/2004.09548 Years: 2020 Credit Novelty and Question set up 主流的立体匹配模型的代价聚合操作主要用了3D卷积&#xff0c;这部分操作的算力和内存消耗过大&#xff0c;因此作者提出一种新的模型AANet&#x…

C#项目--GridControl数据绑定及数据引入

系列文章 C#项目–业务单据号生成器&#xff08;定义规则、自动编号、流水号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 C#项目–开始日期结束日期范围计算&#xff08;上周、本周、明年、前年等&#xff09; 本文链接&…

KUKA机器人修改机器人名称和IP地址的具体方法示例

KUKA机器人修改机器人名称和IP地址的具体方法示例 修改机器人名称 如下图所示,首先切换用户组到管理员,输入默认密码:kuka, 如下图所示,点击菜单键—投入运行—机器人数据, 如下图所示,此时可以看到机器人的名称为rrr445, 如下图所示,修改之后,点击左侧的“”…