大连企业公司网站建设/新乡百度网站优化排名
Element-UI组件el-table用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
将使用到以下两项,来完成今天demo演示:
多级表头:数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。
合并行或列:多行或多列共用一个数据时,可以合并行或列。
官方文档地址: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 数据处理
如上图会发现,科目和成绩相关信息,未显示出来。这里需要对数据进行处理下,将所有科目信息调整到 和姓名字段为同一行数据中。需要做以下几步:
将subject二级数据全部移至name同级的同一行数据中。
将name字段原数据移至subject的第一行数据中;item和sub进行合并。
无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 endtmpData.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 endtmpData.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);//总分和满分总分 被合并部分单元格填写为0subData['columnIndex6'] = { columnIndex: 6, rowspan: 0, colspan: 0 };subData['columnIndex8'] = { columnIndex: 8, rowspan: 0, colspan: 0 };}//if endtmpData.push( subData );});}//无子项数据,保留当前位置输出else{tmpData.push(Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 1, colspan: 1 } }, item));}});return tmpData;
}
此时,咱们需要的表格就被渲染出来了,如下图:

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

Element-UI实现复杂table表格结构
Element-UI组件el-table用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。将使用到以下两项,来完成今天demo演示:多级表头:数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。合…...

Azure AD 与 AWS 单一帐户SSO访问集成,超详细讲解,包括解决可能出现的错误问题
本教程介绍如何将 AWS Single-Account Access 与 Azure Active Directory (Azure AD) 相集成。 将 AWS Single-Account Access 与 Azure AD 集成后,可以: 在 Azure AD 中控制谁有权访问 AWS Single-Account Access。让用户使用其 Azure AD 帐户自动登录…...

lvgl 笔记 按钮部件 (lv_btn) 和 开关部件 (lv_switch)
按钮基础使用方法: lv_btn 和 lb_obj 使用方法一样,只是外表并不相同,基础创建方法只需一行代码。 lv_obj_t* btn lv_btn_create(lv_scr_act()); 添加大小和位置: lv_obj_t* btn lv_btn_create(lv_scr_act()); lv_obj_set_s…...

Python高频面试题——生成器(最通俗的讲解)
生成器定义在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。 在调用生成器运行的过程中…...

品牌软文怎么写?教你几招
软文是什么?软文的本质就是广告,当然不是明晃晃的推销,而是自然隐晦地植入产品信息,引导更多用户自愿下单。 品牌软文对于写手的经验、内容的质量要求都相对较高,否则写出来的软文无法达到预期的效果。品牌软文怎么写…...

Kubernetes (k8s) 污点(Taint)介绍、示例
Kubernetes (k8s) 污点(Taint) 是一种机制,用于标记一个节点(Node)不可被调度的状态。它可以将一个污点标记添加到节点上,以防止 Pod 被调度到该节点上。污点可以用于实现各种策略,例如分离故障…...

Docker学习(二十一)构建 java 项目基础镜像
目录1.下载 JDK 包2.编写 Dockerfile3.构建镜像4.创建容器测试1.下载 JDK 包 JDK各版本官网下载地址: https://www.oracle.com/java/technologies/downloads/archive/#JavaSE 这里我们以 JDK 8u351 为例,点击 Java SE (8U211 and later)。 点击下载 jd…...

python中的上下文原理
目录with语句上下文管理器原理自定义上下文管理器contextmanager 装饰器with语句 在我们日常使用场景中,经常会操作一些资源,比如文件对象、数据库连接、Socket连接等,资源操作完了之后,不管操作的成功与否,最重要的事…...

可复用测试用例描述要素
测试用例的输入、操作、预期结果和评估标准、前提条件是测试用例不可少的要素,但对于可复用测试用例而言,这是不够的。本文在文献规定的测试用例要素基础上,增加了新的内容。从而从多个角度完整地对可复用测试用例进行了描述,为可…...

lnmp中遇到open_basedir配置无效问题
在使用LNMP包安装PHP时,发现直接修改php.ini的配置是无法生效的,其原因竟然是因为nginx的配置文件,覆盖了php.ini的配置。 解决: 1、找到nginx的open_basedir配置文件:(下面是我的文件地址) …...

SpringBoot【知识加油站】---- REST开发
SpringBoot【知识加油站】---- REST开发1. REST 简介2. REST 风格3. RESTful 入门案例1. REST 简介 REST:Representaional State Transfer,表现形式状态转换 传统风格资源描述形式 http://localhost/user/getById?id1 http://localhost/user/saveUser…...

三 Go的语言容器
1. 数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,所以在Go语言中很少直接使用数组 声明语法: var 数组变量名 [元素数量]Typepackage main import ("fmt" ) fu…...

2023年全国最新会计专业技术资格精选真题及答案16
百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 一、单选题 1.下列各项关于会计监督职能的表述中,正确的是ÿ…...

模板进阶(仿函数,特化等介绍)
非类型模板参数 模板参数有类型形参和非类型形参; 类型形参:使用typename或者class修饰的参数类型名称 非类型形参:一个普通常量作为模板参数形参,不能为浮点数,字符类型以及类对象; #include<iostrea…...

Beats:在 Docker 中同时部署 Metricbeat 和 Elasticsearch
在本教程中,我们将部署一个 metricbeat 来监控正在运行的容器的健康状况和系统指标。 为什么需要监控,为什么需要 Metricbeat? 一个常见的问题,但很少有人回答。 首先,无论我们部署的是 docker 容器还是老式的金属箱&…...

编码技巧——Redis Pipeline
本文介绍Redis pipeline相关的知识点及代码示例,包括Redis客户端-服务端的一次完整的网络请求、pipeline与client执行多命令的区别、pipeline与Redis"事务"、pipeline的使用代码示例; pipeline与client执行多命令的区别 Redis是一种基于客户…...

ArcGIS制图技巧:制图入门与点、线、面状符号制作
目的: 1、了解地图制作目的; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念; 6、理解地形点状符号、线状符号、面状符…...

Java基础 关于字典数据维护接口设计
开发环境 Eclipse2022JDK1.8 目录 1. 概述 2. 实现步骤 2.1 定义通用接口 2.2 定义实体类 2.3 接口扩展 2.4 接口实现 2.5 功能测试 3. 结语 1. 概述 每一个信息系统或多或少都带有一些数据字典,在维护上,基本上分为增删改查,也就是对数据…...

从零开始学架构——复杂度来源
复杂度来源——高性能 对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机,从电子管计算机到晶体管计算机再到集成电路计算机,运算性能从每秒几次提升到每秒几亿次。但伴随性能越来越高,相应的方法和系统复杂度也是越来越高。现代的计算机CPU集成…...

什么时候需要分表分库?
在当今互联网时代,海量数据基本上是每一个成熟产品的共性,特别是在移动互联网产品中,几乎每天都在产生数据,例如,商城的订单表、支付系统的交易明细以及游戏中的战报等等。对于一个日活用户在百万数量级的商城来说&…...

冰刃杀毒工具使用实验(29)
实验目的 (1)学习冰刃的基本功能; (2)掌握冰刃的基本使用方法;预备知识 windows操作系统的基本知识,例如:进程、网络、服务和文件等的了解。 冰刃是一款广受好评的ARK工…...

聊聊图像分割的DICE和IOU指标
目录 1. 介绍 2. dice 和 iou 的联系 3. 代码实现 3.1 dice 3.2 iou 3.3 test 3.4 dice 和 iou 的关系曲线 4. 代码 1. 介绍 dice 和 iou 都是衡量两个集合之间相似性的度量 dice计算公式: iou计算公式: iou的集合理解: iou 其实就…...

软件设计师教程(十)计算机系统知识-结构化开发
软件设计师教程 软件设计师教程(一)计算机系统知识-计算机系统基础知识 软件设计师教程(二)计算机系统知识-计算机体系结构 软件设计师教程(三)计算机系统知识-计算机体系结构 软件设计师教程(…...

链表OJ之 快慢指针法总结
欢迎来到 Claffic 的博客 💞💞💞 前言: 快慢指针指的是每次指针移动的步长,是解决链表相关的题目的一大利器,下面我将以例题的形式讲解快慢指针法。 目录 一. 链表的中间结点 思路: 代码实…...

C++STL详解(五)——list的介绍与使用
文章目录list的介绍list的使用list的定义方法list迭代器失效问题list插入和删除inserteraselist迭代器的使用begin,end 和 rbegin,rendlist元素访问front 和 backlist容量控制与数据清理resizeclearlist操作函数spliceremove 和 remove_ifuniquemergerev…...

进程和进程的调度
今天,为大家带来进程和进程的调度的学习 1.认识计算机 2.什么是操作系统 3.什么是进程 4.进程管理 5.进程的属性 6.进程的调度 7.进程调度的过程 8.内存分配 1.认识计算机 计算机的组成有五大部分 1.CPU(是计算机的大脑,负责逻辑运算和控制) 2.内存 3.外存 4.输入…...

TypeScript 深度剖析:TypeScript 的理解?与 JavaScript 的区别?
一、是什么 TypeScript 是 JavaScript 的类型的超集,支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等 超集,不得不说另外一个概念,子集,怎么理解这两个呢,举个例子,如…...

美颜SDK关键技术讲解——人脸识别与人脸美化
拍摄,自从智能手机普及之后就已经不再是小众爱好,使用手机拍摄记录生活几乎成了人们的日常。在巨量的需求下,美颜工具、美颜SDK已经被广泛应用于各大视频拍摄平台。虽然经常听到美颜SDK,但是大多数人并不了解它,下文小…...

Linux下C/C++ 网络扫描(主机扫描技术)
主机扫描是网络扫描的基础,通过对目标网络中主机IP地址的扫描,从一堆主机中扫描出存活的主机,然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制,检查打开的进程,开放的端口号等等。 主机…...

无法将“vue-cli-service”项识别为 cmdlet、函数、脚本文件或不是内部命令的原因和解决方案
经常有小伙伴问我说,为什么我们在开发vue项目的时候,需要在package.json的script对象中,去设置命令启动项目,而不是直接的通过"vue-cli-service serve"命令去把项目跑起来。带着这些疑问,小生在此总结了以下…...