ElementUI 树转表格-----跨行跨列(五)
2022-08-30 本文已影响0人
Cherry丶小丸子
WX20220831-122854.png
template
<template>
<div class="competenceMatrix">
<div class="topBlock">
<!-- 筛选项不写了 -->
</div>
<div class="tableTips">
<ul class="tipsBlock">
<li v-for="(item, index) of tipsBlock" :style="{ 'border-color': colorList[index % 10] }" :key="index">{{ item }}</li>
</ul>
</div>
<div class="tableBlock" ref="tableBlock">
<el-table
v-loading="loading"
element-loading-text="正在加载中,请稍候"
element-loading-spinner="el-icon-loading"
element-loading-background="#fff"
:data="tableData"
row-key="id"
border
class="table"
:span-method="tableSpanMethod"
:max-height="tableMaxHeight"
:header-cell-class-name="headerCellClassName"
:cell-class-name="cellClassName">
<el-table-column width="40" fixed :resizable="false" prop="firstCol">
<template slot="header" slot-scope="scope">
<div style="width: 439px; height: 159px">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<line x1="0" y1="0" x2="439" y2="119" style="stroke: #d9deea; stroke-width: 2" />
<line x1="0" y1="0" x2="439" y2="159" style="stroke: #d9deea; stroke-width: 2" />
<line x1="0" y1="0" x2="300" y2="159" style="stroke: #d9deea; stroke-width: 2" />
<text x="350" y="65" fill="#000">能力体系</text>
<text x="385" y="132" fill="#000" class="fs-12">通用能力</text><!-- fs-12 只是设置字体大小的 -->
<text x="320" y="150" fill="#000">产品</text>
<text x="90" y="150" fill="#000">职能体系</text>
</svg>
</div>
</template>
<template slot-scope="scope">
<div class="textDiv">
{{ scope.row.firstCol }}
</div>
</template>
</el-table-column>
<el-table-column width="130" fixed :resizable="false" prop="secondCol"></el-table-column>
<el-table-column width="130" fixed :resizable="false" prop="thirdCol"></el-table-column>
<el-table-column width="140" fixed :resizable="false" prop="fourthCol"></el-table-column>
<el-table-column v-for="(item, index) of tableHeadData" :label="item.label" align="center" :resizable="false" :label-class-name="'cellBgColor' + index % 10">
<el-table-column v-for="item2 of item.children" :label="item2.label" align="center" :resizable="false" :label-class-name="'cellBgColorTRP' + index % 10">
<el-table-column v-for="item3 of item2.children" :label="item3.label" align="center" :resizable="false">
<el-table-column v-for="item4 of item3.children" align="center" :resizable="false" :prop="item4.prop" :min-width="flexLabelWidth(item3.label)">
<template slot="header" slot-scope="scope">
<div class="flagWrapper" v-if="item4.value">
<div class="yellowFlag"></div>
</div>
</template>
<template slot-scope="scope">
<div class="flagWrapper" v-if="scope.row[scope.column.property]">
<div class="blueFlag"></div>
</div>
</template>
</el-table-column>
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
</div>
</div>
</template>
js
export default {
data(){
return {
tipsBlock: ['维护服务', '软件工程', '数据工程', '规划设计', '咨询服务', '能力外协'],
loading: false,
tableMaxHeight: 0,
tableHeadData: [{
"label": "维护服务",
"children": [
{
"label": "安装部署",
"children": [
{
"label": "安装部署",
"children": [
{
"prop": "135e3cdb-fc35-11ec-b676-848f69de21c9",
"value": true
}
]
}
],
},
{
"label": "运维支持",
"children": [
{
"label": "运维支持",
"children": [
{
"prop": "33d9c8bb-fc35-11ec-b676-848f69de21c9",
"value": false
}
]
}
]
}
],
}],
tableData: [{
"firstCol": "自然资源",
"secondCol": "资源调查监测",
"thirdCol": "基础调查1",
"fourthCol": "自然资源一张图",
"33d9c8bb-fc35-11ec-b676-848f69de21c9": false,
"135e3cdb-fc35-11ec-b676-848f69de21c9": true,
}],
colorList: ['#2572FF', '#1DD08D', '#19B1FC', '#FA8B15', '#FF6364', '#7893FF', '#9934F1', '#EAFF00', '#00E5FF', '#6CDAF5']
}
},
methods: {
/**
* 表格 header ----- 单元格设置类名 ----- 实现表头跨列
* @param row
* @param column
* @param rowIndex
* @param columnIndex
* @returns {{}}
*/
headerCellClassName({row, column, rowIndex, columnIndex}){
if(rowIndex === 0 && columnIndex === 0){
// 一定要写在加载完毕后,nextTick 更新的最晚,才能获取到 dom 节点
this.$nextTick(() =>{
let header = document.querySelector('.el-table__header-wrapper');
let fixedHeader = document.querySelector('.el-table__fixed');
header.getElementsByClassName(column.id)[0].setAttribute('colSpan','4');
fixedHeader.getElementsByClassName(column.id)[0].setAttribute('colSpan','4');
// document.getElementsByClassName(column.id)[0].setAttribute('colSpan','4');
})
return 'specialHeaderCell'
}
if (rowIndex === 0 && 1 <= columnIndex && columnIndex <= 3){
return 'specialOtherCell'
}
},
/**
* 表格 body ----- 单元格设置类名
* @param row
* @param column
* @param rowIndex
* @param columnIndex
*/
cellClassName({row, column, rowIndex, columnIndex}){
let classNameList = ['tableBodyFirstCol', 'tableBodySecondCol', 'tableBodyThirdCol', 'tableBodyFourthCol'];
return classNameList[columnIndex];
},
/**
* 合并行或列的计算方法
*/
tableSpanMethod({row, column, rowIndex, columnIndex}){
return {
rowspan: columnIndex <= 1 ? this.mergeRows(row[column.property], this.tableData, rowIndex, column.property) : 1,
colspan: 1
};
},
/**
* 表格单元格合并-----行
* @param {Object} value 当前单元格的值
* @param {Object} data 当前表格所有数据
* @param {Object} index 当前单元格的值所在 行 索引
* @param {Object} property 当前列的property
* @returns {number} 待合并单元格数量
*/
mergeRows(value, data, index, property) {
// 判断 当前行的该列数据 与 上一行的该列数据 是否相等
if (index !== 0 && value === data[index - 1][property]) {
// 返回 0 使表格被跨 行 的那个单元格不会渲染
return 0;
};
// 判断 当前行的该列数据 与 下一行的该列数据 是否相等
let rowSpan = 1;
for (let i = index + 1; i < data.length; i++) {
if (value !== data[i][property]) {
break;
};
rowSpan++;
};
return rowSpan;
},
/**
* 表格表头列宽度自适应
* @param str
* @returns {string}
*/
flexLabelWidth(str){
let flexWidth = 0;
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符,为字符分配 8 个单位宽度
flexWidth += 8;
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符,为字符分配 15个 单位宽度
flexWidth += 20;
} else {
// 其他种类字符,为字符分配 8 个单位宽度
flexWidth += 9;
}
}
if (flexWidth < 80) {
// 设置最小宽度
flexWidth = 80;
}
// if (flexWidth > 250) {
// // 设置最大宽度
// flexWidth = 250;
// }
return flexWidth + 'px';
}
}
}
css
.competenceMatrix{
height: 100%;
width: 100%;
box-sizing: border-box;
.topBlock{}
.tableTips{
margin: 14px 0;
height: 32px;
padding: 0 20px;
.tipsBlock{
li{
width: 80px;
height: 32px;
line-height: 32px;
text-align: center;
float: left;
margin-right: 16px;
box-sizing: border-box;
border-bottom: 2px solid;
}
}
}
.tableBlock{
height: calc(100% - 120px);
padding: 0 20px;
::v-deep .table{
.el-table__header-wrapper,.el-table__fixed-header-wrapper{
thead{
tr{
td{
padding: 0;
}
th{
padding: 0;
}
}
tr:nth-child(1),tr:nth-child(2){
th{
.cell{
color: #fff;
}
}
}
tr:nth-child(4){
th{
background: #fff;
border-color: #D9E7FF;
}
}
}
.specialHeaderCell{
background: #f0f0fc;
}
.specialOtherCell{
display: none;
}
.cell{
padding: 0;
width: 100%;
height: 100%;
line-height: 39px;
color: #000;
font-size: 14px;
}
.cellBgColor0{
background: rgba(37, 114, 255, 1);
}
.cellBgColorTRP0{
background: rgba(37, 114, 255, 0.5);
}
.cellBgColor1{
background: rgba(29, 208, 141, 1);
}
.cellBgColorTRP1{
background: rgba(29, 208, 141, 0.5);
}
.cellBgColor2{
background: rgba(25, 177, 252, 1);
}
.cellBgColorTRP2{
background: rgba(25, 177, 252, 0.5);
}
.cellBgColor3{
background: rgba(250, 139, 21, 1);
}
.cellBgColorTRP3{
background: rgba(250, 139, 21, 0.5);
}
.cellBgColor4{
background: rgba(255, 99, 100, 1);
}
.cellBgColorTRP4{
background: rgba(255, 99, 100, 0.5);
}
.cellBgColor5{
background: rgba(120, 147, 255, 1);
}
.cellBgColorTRP5{
background: rgba(120, 147, 255, 0.5);
}
.cellBgColor6{
background: rgba(153, 52, 241, 1);
}
.cellBgColorTRP6{
background: rgba(153, 52, 241, 0.5);
}
.cellBgColor7{
background: rgba(234, 255, 0, 1);
}
.cellBgColorTRP7{
background: rgba(234, 255, 0, 0.5);
}
.cellBgColor8{
background: rgba(0, 229, 255, 1);
}
.cellBgColorTRP8{
background: rgba(0, 229, 255, 0.5);
}
.cellBgColor9{
background: rgba(108, 218, 245, 1);
}
.cellBgColorTRP9{
background: rgba(108, 218, 245, 0.5);
}
}
.el-table__body-wrapper,.el-table__fixed-body-wrapper{
.tableBodyFirstCol{
background: #5F7292;
.textDiv{
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
align-items: center;
width: 20px;
margin: 0 auto;
line-height: 1.6;
color: #fff;
}
}
.tableBodySecondCol{
background: #a0aabf;
color: #fff;
}
.tableBodyThirdCol{
background: #eceef0;
color: #333;
}
.tableBodyFourthCol{
background: #f6f9fa;
color: #000;
}
}
}
}
}
.flagWrapper{
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.yellowFlag{
width: 28px;
height: 28px;
background: url("../../assets/images/common/icon-yellow-flag.png");
}
.blueFlag{
width: 28px;
height: 28px;
background: url("../../assets/images/common/icon-blue-flag.png");
}
}