头图

废话不多说,先看效果如下,我固定的是前三列,复杂表头渲染,是我前一章节说的https://segmentfault.com/a/11...
复杂表头固定前n列

1、elementui的table的多级表头固定前n列(注意:n列是根据width来固定的)的问题所在

1.1 发现给了el-column固定宽度,和fixed属性后,其他没有这两个属性的el-column部分被加上了is-hidden的类名(这个要浏览器控制台查看html结构代码才知道),导致页面渲染的数据被隐藏了,所以要想办法去掉这个类名
1.2 经过查看html结构后,使用jquery去掉is-hidden类名(没有想到更好的办法,有其他办法的大神希望能点拔我一下)

2、解决的办法:

2.1 核心代码:
this.$nextTick(() => {
                    // 如果不是固定列用这个
                    let myTrList = $('.kingChangeHead .el-table__header .has-gutter tr');
                    // 第一行表头(表头的样式)
                    let colorTr = myTrList.eq(0);
                    let colorTh = colorTr.find('th').eq(0);
                    $(colorTh).removeClass('is-hidden');
                    $(colorTh)
                        .find('.cell')
                        .css({ color: '#000', 'font-size': '18px', 'font-weight': 'bold' });
                    /**
                     * @Date: 2021-08-17
                     * @author @拿菜刀砍电线
                     * @Description:为了解决elementui的复杂表头,固定前三列的问题
                     * 问题分析1、发现给了固定宽度,和fixed属性后,没有固定的部分被加上了is-hidden的类名,导致页面数据被隐藏了,所以要想办法去掉这个类名
                     * 2、经过查看html结构后,使用jquery去掉is-hidden类名
                     */
                    let kingBody = $('.kingChangeHead .el-table__body-wrapper .el-table__body tr');
                    kingBody.each(function(index, domEle) {
                        $(domEle)
                            .find('td')
                            .each(function(index1, domEle1) {
                                $(domEle1).removeClass('is-hidden');
                            });
                    });
                    if (this.$refs.mutipleTable !== undefined) {
                        this.$refs.mutipleTable.doLayout();
                    }
                });
2.2 全部代码:

<template>
    <div class="barCodeManageIndex">
        <div>
            <div class="collapseContent">
                <div id="searchForm" class="collapseCon">
                    <el-form label-position="right">
                        <div class="l-f">
                            <el-form-item label="年份:" label-width="50px">
                                <el-date-picker :clearable="false" format="yyyy" value-format="yyyy" v-model="searchForm.year" type="year" placeholder="请选择"></el-date-picker>
                            </el-form-item>
                            <el-form-item label="月份:" label-width="50px">
                                <el-select :clearable="false" v-model.trim="searchForm.month" placeholder="请选择">
                                    <el-option v-for="(item, index) in monthList" :key="index" :label="item.label" :value="item.value"></el-option>
                                </el-select>
                            </el-form-item>
                        </div>
                    </el-form>
                </div>
            </div>
        </div>
        <div class="collapseContent">
            <div @click.self="show = !show" class="l-f l-flex-c collapseCon pointer">
                <i @click.self="show = !show" class="el-icon-arrow-up o-mr-40" :class="{ isRotate: !show }"></i>
                <el-button class="o-ml-12" icon="el-icon-zoom-in" v-preventReClick type="goon" size="mini" @click="searchAll">查询</el-button>
                <el-button class="o-ml-12" icon="el-icon-my-export" v-preventReClick type="success" size="mini" @click="exportFile">导出</el-button>
                <el-button class="o-ml-12 kingButton" icon="el-icon-full-screen" v-preventReClick type="success" size="mini" @click="clickFullscreen('kingFullScreen')">
                    全屏显示
                </el-button>
            </div>
            <div>
                <el-collapse-transition>
                    <div v-show="show">
                        <div class="showToolTip changeElBoCoSt kingChangeHead">
                            <el-table
                                id="kingFullScreen"
                                v-loading="loading"
                                :cell-style="sca_CellStyle"
                                border
                                highlight-current-row
                                :height="clientHeight"
                                resizable
                                :data="tableData"
                                ref="mutipleTable"
                                :span-method="objectSpanMethod"
                                :header-cell-style="headerCellStyleNameKing"
                                :row-style="selectedHighlight_custom"
                            >
                                <el-table-column fixed width="300" :label="subCompanyMonth + '月-五大战区各项质量汇总'" align="center">
                                    <el-table-column fixed :index="kingIndex" type="index" label="序号" width="60" align="center"></el-table-column>
                                    <el-table-column fixed prop="type" label="类型" width="120" align="center">
                                        <template slot-scope="scope">
                                            <span v-if="scope.$index == 0" style="font-weight: bold;">
                                                各区排名
                                                <span style="color: blue;">第一</span>
                                                项目个数
                                            </span>
                                            <span v-else-if="scope.$index == 1" style="font-weight: bold;">
                                                各区排名
                                                <span style="color: red;">最后</span>
                                                项目个数
                                            </span>
                                            <span v-else>{{ scope.row.type }}</span>
                                        </template>
                                    </el-table-column>
                                    <el-table-column fixed prop="project" label="项目" width="120" align="center"></el-table-column>
                                    <el-table-column
                                        v-if="tableData && tableData.length > 0"
                                        v-for="(value1, key, index) in tableDataDetail"
                                        :key="index + 'day'"
                                        :label="key"
                                        align="center"
                                    >
                                        <el-table-column v-for="(value2, key2, index2) in value1" :key="index2" :label="key2" align="center">
                                            <el-table-column v-for="(item1, index1) in value2" :key="index1" :label="item1.name" align="center">
                                                <template slot-scope="scope">
                                                    <span
                                                        :style="{
                                                            color: scope.row.daySale[key][key2][index1]['color'],
                                                            fontWeight: scope.row.daySale[key][key2][index1]['fontBold']
                                                        }"
                                                    >
                                                        {{ scope.row.daySale[key][key2][index1]['value'] }}
                                                    </span>
                                                </template>
                                            </el-table-column>
                                        </el-table-column>
                                    </el-table-column>
                                </el-table-column>
                            </el-table>
                        </div>
                    </div>
                </el-collapse-transition>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'brCoInAn_daRe_ovSuOfThZone',
    data() {
        return {
            // 代表的月份
            subCompanyMonth: '',
            formLabelWidth: '120px',
            searchFormLableWidth: '100px',
            // 查询参数
            searchForm: {
                month: '',
                year: null
            },
            show: true,
            tableData: [],
            // 表格高度
            clientHeight: null,
            // 统计合并多少行
            needMergeArr: ['type'], // 有合并项的列
            rowMergeArrs: {} // 包含需要一个或多个合并项信息的对象
        };
    },
    computed: {
        monthList() {
            let monthList = [];
            for (var i = 1; i < 13; i++) {
                monthList.push({
                    label: `${i}月`,
                    value: i
                });
            }
            return monthList;
        },
        loading() {
            return this.GetStore('globalNotice', 'kingLoading');
        },
        tableDataDetail() {
            let tableData = [];
            if (this.tableData && this.tableData.length > 0) {
                tableData = this.tableData[0]['daySale'];
            }
            return tableData;
        }
    },
    mounted() {
        this.searchForm.year = this.GetCurrentTime().orderYear;
        this.searchForm.month = Number(this.GetCurrentTime().yearMonth.substring(5, 7));
        // 自定义table的宽度,为了固定表头
        this.clientHeight = document.body.clientHeight - 230;
        const that = this;
        window.onresize = () => {
            return (() => {
                window.clientHeight = document.body.clientHeight;
                that.clientHeight = window.clientHeight - 230;
            })();
        };
    },
    updated() {
        this.$nextTick(() => {
            if (this.$refs.mutipleTable !== undefined) {
                this.$refs.mutipleTable.doLayout();
            }
        });
    },
    methods: {
        // 第一第二行背景色
        selectedHighlight_custom({ row, rowIndex }) {
            // if (rowIndex == 0 || rowIndex == 1) {
            //     return {
            //         'background-color': '#ddd'
            //     };
            // }
        },
        // 点击导出按钮
        exportFile() {
            this.exportFile_king(this.$api.reBrGuAnalyAreaexportReport, this.searchForm);
        },
        /**
         * @description 实现合并行或列
         * @param row:Object 需要合并的列name 如:'name' 'id'
         * @param column:Object 当前行的行数,由合并函数传入
         * @param rowIndex:Number 当前列的数据,由合并函数传入
         * @param columnIndex:Number 当前列的数据,由合并函数传入
         *
         * @return 函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,
         * 第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象
         */
        objectSpanMethod({ row, column, rowIndex, columnIndex }) {
            // 第一行的达成,环比,排名,列合并
            if (rowIndex === 0 || rowIndex === 1) {
                if (column.label == '达成') {
                    return [1, 3];
                } else if (column.label == '环比') {
                    return [0, 0];
                } else if (column.label == '排名') {
                    return [0, 0];
                }
            }
            // 第一,第二行的1,2,3列合并
            if (rowIndex === 0 || rowIndex === 1) {
                if (columnIndex === 0) {
                    return [0, 0];
                } else if (columnIndex === 1) {
                    return [1, 3];
                } else if (columnIndex === 2) {
                    return [0, 0];
                }
            }
            // 方法二:(合并行)
            for (let key in this.rowMergeArrs) {
                if (column.property == key) {
                    let _row = this.rowMergeArrs[key].rowArr[rowIndex];
                    let _col = _row > 0 ? 1 : 0;
                    return [_row, _col];
                }
            }
        },
        // 用来合并表头的(label为“整体”的上下两行合并)
        headerCellStyleNameKing({ row, column, rowIndex, columnIndex }) {
            if (rowIndex === 0) {
                this.$nextTick(() => {
                    if ($('.' + column.id).length !== 0) {
                        $('.' + column.id + ' .cell').css({ color: '#111', 'font-weight': 'bold' });
                    }
                });
                return column;
            } else if (rowIndex === 2) {
                if (column.label == '整体') {
                    this.$nextTick(() => {
                        if ($('.' + column.id).length !== 0) {
                            $('.' + column.id + ' .cell').css({ color: '#111', 'font-weight': 'bold', 'font-size': '20px' });
                            $('.' + column.id).attr('rowspan', 2);
                            // var _c = document.getElementsByClassName(column.id);
                            // document.getElementsByClassName(column.id)[0].setAttribute('rowSpan', 2);
                        }
                    });
                    return column;
                } else {
                    return {
                        textAlign: 'center',
                        color: '#111111',
                        fontSize: '16px',
                        fontWeight: 400
                    };
                }
            } else if (rowIndex === 3) {
                if (column.label == '整体') {
                    return { display: 'none' };
                } else {
                    return {
                        textAlign: 'center',
                        color: '#111111',
                        fontSize: '16px',
                        fontWeight: 400
                    };
                }
            } else {
                return {
                    textAlign: 'center',
                    color: '#111111',
                    fontSize: '16px',
                    fontWeight: 400
                };
            }
        },
        // 解决下标从第二行开始,(数字要从1开始)
        kingIndex(index) {
            if (index != 0 || index != 1) {
                return index - 1;
            }
        },
        searchAll() {
            this.tableData = [];
            this.getList();
        },
        getList() {
            // 因为时间是一定要的,如果用户没有选择时间,要强制
            if (!this.searchForm.year) {
                this.searchForm.year = this.GetCurrentTime().orderYear;
            }
            if (!this.searchForm.month) {
                this.searchForm.month = Number(this.GetCurrentTime().yearMonth.substring(5, 7));
            }
            // 表头数据
            this.subCompanyMonth = this.searchForm.month || '';
            this.$store.commit('Edit_loading', true);
            let param = this.searchForm;
            this.$method(this.$api.reBrGuAnalygetAreaSumReport, 'post', param).then(res => {
                if (res.data && res.data.length > 0) {
                    res.data.forEach((item, index) => {
                        for (let key in item.daySale) {
                            for (let key1 in item.daySale[key]) {
                                item.daySale[key][key1].forEach((item1, index1) => {
                                    // 颜色和加粗
                                    item1.color = null;
                                    item1.fontBold = null;
                                    // 如果有值
                                    if (item1.value != null) {
                                        // 有没有变色
                                        if (item1.isRanking == 1) {
                                            item1.color = 'blue';
                                            item1.fontBold = 'bold';
                                        } else if (item1.isRanking == 2) {
                                            item1.color = 'red';
                                            item1.fontBold = 'bold';
                                        }
                                        // 看是不是整数类型
                                        // 2代表为整数
                                        if (item1.algorithm != 2 && item1.algorithm != 4 && item1.algorithm != null) {
                                            item1.value = this.Big(item1.value).mul(100) + '%';
                                        }
                                    } else {
                                        item1.value = '-';
                                    }
                                });
                            }
                        }
                    });
                }
                this.tableData = res.data;
                // 处理数据
                this.rowMergeArrs = this.rowMergeHandle(this.needMergeArr, this.tableData);
                this.$nextTick(() => {
                    // 如果不是固定列用这个
                    let myTrList = $('.kingChangeHead .el-table__header .has-gutter tr');
                    // 第一行表头(表头的样式)
                    let colorTr = myTrList.eq(0);
                    let colorTh = colorTr.find('th').eq(0);
                    $(colorTh).removeClass('is-hidden');
                    $(colorTh)
                        .find('.cell')
                        .css({ color: '#000', 'font-size': '18px', 'font-weight': 'bold' });
                    /**
                     * @Date: 2021-08-17
                     * @author @拿菜刀砍电线
                     * @Description:为了解决elementui的复杂表头,固定前三列的问题
                     * 问题分析1、发现给了固定宽度,和fixed属性后,没有固定的部分被加上了is-hidden的类名,导致页面数据被隐藏了,所以要想办法去掉这个类名
                     * 2、经过查看html结构后,使用jquery去掉is-hidden类名
                     */
                    let kingBody = $('.kingChangeHead .el-table__body-wrapper .el-table__body tr');
                    kingBody.each(function(index, domEle) {
                        $(domEle)
                            .find('td')
                            .each(function(index1, domEle1) {
                                $(domEle1).removeClass('is-hidden');
                            });
                    });
                    if (this.$refs.mutipleTable !== undefined) {
                        this.$refs.mutipleTable.doLayout();
                    }
                });
            });
        }
    }
};
</script>

<style lang="scss">
.changeElBoCoSt {
    .el-table .cell {
        color: #333;
    }
    .el-table__header {
        // border-right: 1px solid #000;
        border-top: 1px solid #000;
        border-left: 1px solid #000;
    }
    .el-table__body {
        // border-right: 1px solid #000;
        // border-bottom: 1px solid #000;
        border-left: 1px dashed #000;
    }

    .el-table--border td {
        border-right: 1px dashed #000;
    }
    .el-table--border th {
        border-right: 1px solid #000;
    }
    .el-table__body-wrapper .el-table--border.is-scrolling-left ~ .el-table__fixed {
        border-right: 1px dashed #000;
    }

    .el-table--border th {
        border-bottom: 1px solid #000;
    }

    .el-table__fixed-right-patch {
        border-bottom: 1px dashed #000;
    }

    .el-table td {
        border-bottom: 1px dashed #000;
    }
    .el-table th.is-leaf {
        border-bottom: 1px solid #000;
    }

    .el-table__header tr,
    .el-table__header th {
        background-color: #ffc000 !important;
    }
    // // body的每一行的最后一个单元格
    // .el-table__body tr td:last-child {
    //     border-right: 1px solid #000;
    // }
    // // body的最后一行
    // .el-table__body tr:last-child td {
    //     border-bottom: 1px solid #000;
    // }
    // //(刚好最后两行的第一列有合并才要这个)
    // .el-table__body tr:first-child td:first-child {
    //     border-bottom: 1px solid #000;
    // }

    // 双下划线(表体)
    // .kingRowIndex td {
    //     border-bottom: 2px solid #000000 !important;
    // }
    // 表头
    // .kingRowIndex1 {
    //      border-right: 2px solid #000000 !important;
    // }
}
</style>

浪迹天涯小king
15 声望1 粉丝