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");
    }
}
上一篇下一篇

猜你喜欢

热点阅读