Element-UI组件el-table用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
将使用到以下两项,来完成今天demo演示:
多级表头:数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。
合并行或列:多行或多列共用一个数据时,可以合并行或列。
官方文档地址:https://element.eleme.cn/#/zh-CN/component/table
需要实现的表格如下图:
使用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>
此时表头效果已形成,如下图:
数据渲染这里较为复杂,这里为方便大家理解,进行逐步拆解叙述。如有更好方法,也欢迎大家指点。
如上图,在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>
此时表格中可以正常渲染出部分数据了,效果图如下:
如上图会发现,科目和成绩相关信息,未显示出来。这里需要对数据进行处理下,将所有科目信息调整到 和姓名字段为同一行数据中。需要做以下几步:
将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 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>
此时表格效果图如下:
如上图,
列(姓名)位于列的第1位置(起始从0开始,所以序号为第0位置),往下合并subject数组长度位置即可。
列(总分)位于列的第6位置,往下合并subject数组长度位置即可。
列(满分总分)位于列的第8位置,往下合并subject数组长度位置即可。
这是我们会发现,methods中定义的reconstructionStuCell()函数还未使用,通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。
span-method相当于从数据单元格第一行开始,每行每列开始循环执行,想当于 9 * 15 执行135次,通过函数中 rowIndex, columnIndex字段进行判断当前循环是哪行哪列,并作对应处理。
这里我们添加以下逻辑,在每行数据中添加姓名、总分,满分总分对应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 row['columnIndex'+columnIndex];
}
//if end
}
比如执行span-method方法时,此时获取row数据中columnIndex1,columnIndex1中的columnIndex值为1,与span-method方法中columnIndex进行对比。
1、此时每行中列1都会被匹配到,列1行1返回{colspan: 1, rowspan: 5},则往下合并5个单元格;
2、列1行2返回{colspan: 0, rowspan: 0},则单元格不渲染,否则此行多一个单元格会错位;
3、列1行3,列1行4...... 同理。
列6(总分)、列8(满分总分)同理,通过columnIndex6和columnIndex8进行判断,进行单元格合并。
以上代码添加后,发现表格并无任何变化,这是因为重构数据函数中,还未添加对应的columnIndex1、columnIndex6、columnIndex8字段。
首先,我们来合并(姓名)这列数据,将每行数据中添加columnIndex1,子属性变量columnIndex表示合并对应的列位置。
subject有子项数据除第一行数据,后面所有rowspan和colspan为0,第1个单元往下合并后,会填充其他行空缺位置。
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;
}
此时大家看到表格的(姓名)列,已合并到对应长度,效果图如下:
总分和满分总分合并部分,和(姓名)列同理,但多出一步则需计算出对应科目的总分 和 所有科目的满分总分。
增加第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;
}
此时,咱们需要的表格就被渲染出来了,如下图:
reconstructionStuCell()函数中对列的合并参数一一取出,这样会比较繁琐,通过for循环对row行内数据进行查询,并通过columnIndex判断对应列及返回结果。代码如下:
reconstructionCell({ row, column, rowIndex, columnIndex }){
for(var key in row){
//匹配列数据
if(/columnIndex/.test(key)&&'undefined'!==typeof row[key]['columnIndex']){
//关联对应列,并返回合并参数
if(row[key].columnIndex == columnIndex){
return {
rowspan: row[key].rowspan,
colspan: row[key].colspan
}
}
}
}
}
这里reconstructionStuData()函数处理能力还是相对不足,只能处理特定的表格合并。希望对大家有所帮助,仅供大家参考!
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我需要一个表,其中行实际上是2行表,一个嵌套表是..我怎样才能在Prawn中做到这一点?也许我需要延期..但哪一个? 最佳答案 现在支持子表:Prawn::Document.generate("subtable.pdf")do|pdf|subtable=pdf.make_table([["sub"],["table"]])pdf.table([[subtable,"original"]])end 关于ruby-on-rails-PrawnPDF:Ineedtogeneratenested
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO