美文网首页
ElementUI 树转表格-----跨行跨列(五)

ElementUI 树转表格-----跨行跨列(五)

作者: Cherry丶小丸子 | 来源:发表于2022-08-30 14:27 被阅读0次
    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");
        }
    }
    

    相关文章

      网友评论

          本文标题:ElementUI 树转表格-----跨行跨列(五)

          本文链接:https://www.haomeiwen.com/subject/ufrdnrtx.html