vue+element ui实现复杂表格
「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。
一、需求
根据项目需求,需要实现以下形式的一个表格。
二、实现
由于项目所使用的框架为 vue + element ui,所以我们可以考虑使用 element ui 的 Table 表格组件来实现。但是通过了解发现,该组件所需的数据结构似乎并不能满足该功能的实现,通过研究,我们可以自定义表格渲染所需的 JSON 数据,这样的话就能方便实现了,具体做法如下:
1、定义表格组件所需的 JSON 数据(tableData.json)
{
"header_labels": {
"header1_label": {
"label": "商家1",
"children": {
"header1_col1": "",
"header1_col2": "",
"header1_col3": ""
}
},
"header2_label": {
"label": "商家2",
"children": {
"header2_col1": "",
"header2_col2": "",
"header2_col3": ""
}
},
"header3_label": {
"label": "商家3",
"children": {
"header3_col1": "",
"header3_col2": "",
"header3_col3": ""
}
}
},
"col_values": [
{
"header1_col1": "库存(件)",
"header1_col2": "20000",
"header2_col1": "库存(件)",
"header2_col2": "21000",
"header3_col1": "库存(件)",
"header3_col2": "22000"
},
{
"header1_col1": "总销量(件)",
"header1_col2": "15000",
"header2_col1": "总销量(件)",
"header2_col2": "7850",
"header3_col1": "总销量(件)",
"header3_col2": "1500"
},
{
"header1_col1": "日期",
"header1_col2": "上装销量(件)",
"header1_col3": "下装销量(件)",
"header2_col1": "日期",
"header2_col2": "上装销量(件)",
"header2_col3": "下装销量(件)",
"header3_col1": "日期",
"header3_col2": "上装销量(件)",
"header3_col3": "下装销量(件)"
},
{
"header1_col1": "2022.02.01",
"header1_col2": "400",
"header1_col3": "300",
"header2_col1": "2022.02.01",
"header2_col2": "20",
"header2_col3": "300",
"header3_col1": "2022.02.01",
"header3_col2": "40",
"header3_col3": "30"
},
{
"header1_col1": "2022.02.02",
"header1_col2": "700",
"header1_col3": "800",
"header2_col1": "2022.02.02",
"header2_col2": "30",
"header2_col3": "800",
"header3_col1": "2022.02.02",
"header3_col2": "70",
"header3_col3": "80"
},
{
"header1_col1": "2022.02.03",
"header1_col2": "900",
"header1_col3": "1000",
"header2_col1": "2022.02.03",
"header2_col2": "40",
"header2_col3": "1000",
"header3_col1": "2022.02.03",
"header3_col2": "90",
"header3_col3": "100"
},
{
"header1_col1": "2022.02.041",
"header1_col2": "1100",
"header1_col3": "1100",
"header2_col1": "2022.02.04",
"header2_col2": "50",
"header2_col3": "1100",
"header3_col1": "2022.02.04",
"header3_col2": "110",
"header3_col3": "110"
},
{
"header1_col1": "2022.02.05",
"header1_col2": "1300",
"header1_col3": "1200",
"header2_col1": "2022.02.05",
"header2_col2": "60",
"header2_col3": "1200",
"header3_col1": "2022.02.05",
"header3_col2": "130",
"header3_col3": "120"
},
{
"header1_col1": "2022.02.06",
"header1_col2": "1400",
"header1_col3": "1500",
"header2_col1": "2022.02.06",
"header2_col2": "70",
"header2_col3": "1500",
"header3_col1": "2022.02.06",
"header3_col2": "140",
"header3_col3": "150"
},
{
"header1_col1": "2022.02.07",
"header1_col2": "1700",
"header1_col3": "1600",
"header2_col1": "2022.02.07",
"header2_col2": "80",
"header2_col3": "1600",
"header3_col1": "2022.02.07",
"header3_col2": "170",
"header3_col3": "160"
}
]
}
2、JS 中定义表格数据渲染所需变量(tableData),并获取本地 JSON 数据(tableData.json)赋值给 tableData 变量。
<script>
import tableJsonData from '/static/tableData.json'// 引入本地数据
export default {
data() {
return {
tableData: {}
}
},
created() {
this.tableData = tableJsonData
}
}
</script>
3、HTML 页面渲染
<template>
<div class="app-container">
<!-- tableData['col_values']:表格数据 -->
<el-table
:data="tableData['col_values']"
style="width: 100%;"
border
height="600"
>
<!-- tableData['header_labels']:表头数据 -->
<el-table-column
v-for="(value1,key1,index1) in tableData['header_labels']"
:key="index1"
:label="value1['label']"
align="center"
>
<el-table-column
v-for="(value2,key2,index2) in value1['children']"
:key="index2"
align="center"
>
<template slot-scope="scope">
<span>{{ scope.row[key2] }}</span>
</template>
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
4、页面效果
由上图可知,页面的基本效果已经出来了,但是仍然有一些问题需要优化:
- 第二行显然是多余的,我们希望隐藏掉;
- 第三行和第四行,我们希望显示值的部分做一个单元格合并;
- 显示文字的单元格样式做一个修改,使其对比更鲜明;
三、优化
1、隐藏空白行
对于第一点,可以通过设置 Table 组件提供的属性 “header-cell-class-name” 来解决。
首先在 el-table 标签上设置该属性如下:
<el-table
:data="tableData['col_values']"
style="width: 100%;"
border
height="600"
:header-cell-class-name="hiddenHeaderRow"
>
在 methods 中写 hiddenHeaderRow 方法如下:
hiddenHeaderRow({ rowIndex }) {
if (rowIndex === 1) {//隐藏第二行
return 'hiddenClass'
}
},
在 style 中写 hiddenClass 样式如下:
.hiddenClass{
display: none;
}
效果如图,空白行已经被隐藏了:
2、合并单元格
对于第二点,Table 组件也提供了一个属性 "span-method",我们可以通过该属性来实现单元格的合并。
同样的,在 el-table 标签上设置该属性如下:
<el-table
:data="tableData['col_values']"
style="width: 100%;"
border
height="600"
:header-cell-class-name="hiddenHeaderRow"
:span-method="arraySpanMethod2"
>
在 methods 中实现 arraySpanMethod2 方法:
arraySpanMethod2({ rowIndex, columnIndex }) {
if (rowIndex <= 1) {
if (columnIndex % 3 === 1) {
return [1, 2]// 返回的是需要合并的行和列的数量,不是下标,是固定的
} else if (columnIndex % 3 === 2) {
return [0, 0]
}
}
},
效果如图,单元格合并了:
3、样式修改
对于第三点,也可以通过 Table 组件的“cell-class-name”属性来进行修改。
在 el-table 标签上设置该属性如下:
<el-table
:data="tableData['col_values']"
style="width: 100%;"
border
height="600"
:header-cell-class-name="hiddenHeaderRow"
:span-method="arraySpanMethod2"
:cell-class-name="addClass2"
>
在 methods 中实现 addClass2 方法:
addClass2({ rowIndex, columnIndex }) {
if (rowIndex <= 1 && columnIndex % 3 === 0) {
return 'sonStyle'
} else if (rowIndex === 2) {
return 'sonStyle'
}
},
在 style 中定义 sonStyle 样式:
.sonStyle{
font-weight: bold;
background-color: #f0f9eb;
font-size: 14px;
color: #27a2ff;
}
最终效果如图:
关于复杂表格,之前还写过这样一篇文章:vue+element ui 动态实现多元化表格(包括竖型表格,多级表头,单元格合并,可编辑,可折叠以及自定义样式)
转载自:https://juejin.cn/post/7067056903875985416