当前位置:   article > 正文

Vue el-table 多表格联合显示、合并单元格_vue table 合并单元格

vue table 合并单元格

原型图

在这里插入图片描述

分析

先看内容是三个表,每个表的合并单元格都有点不同。
按照原型图给的内容,第一个是两列,有行合并和列合并,还有表头行合并。
现根据图造出mock数据,然后再写对应的代码。

export const columnVarsData = {
    spanArr0: [
        {
            rowIndex: 3,
            columnIndex: 0,
            rowspan: 3,
            colspan: 1
        },
        {
            rowIndex: 0,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 1,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 2,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 6,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 7,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        }
    ],
    spanArr1: [
        {
            rowIndex: 0,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 1,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 3,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 4,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        }
    ],
    spanArr2: [
        {
            rowIndex: 0,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 1,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        },
        {
            rowIndex: 2,
            columnIndex: 0,
            rowspan: 1,
            colspan: 2
        }
    ],
    tableData: [
        {
            title: '汽车',
            columnList: [
                {
                    appName: '汽车1',
                    excessive: '汽车1',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '汽车2',
                    excessive: '汽车2',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '汽车3',
                    excessive: '汽车3',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '银行',
                    excessive: '中国银行',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '银行',
                    excessive: '华夏银行',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '银行',
                    excessive: '农业银行',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '汽车中心',
                    excessive: '汽车中心',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '汽车小计',
                    excessive: '汽车小计',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                }
            ],
            list: [
                {
                    label: '数据',
                    prop: 'appName'
                },
                {
                    label: '数据',
                    prop: 'excessive'
                },
                {
                    label: '昨天',
                    prop: 'yesterdayPendingReview'
                },
                {
                    label: '今天',
                    prop: 'newAddedToday'
                },
                {
                    label: '明天',
                    prop: 'currentAuditCirculation'
                },
                {
                    label: '后天',
                    prop: 'rejectionVolumeToday'
                },
                {
                    label: '大后天',
                    prop: 'remainingQuantityReview'
                }
            ]
        },
        {
            title: '卡车',
            columnList: [
                {
                    appName: '卡车1',
                    excessive: '卡车1',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '卡车2',
                    excessive: '卡车2',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '卡车3',
                    excessive: '卡车4',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '小计',
                    excessive: '小计',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '合计',
                    excessive: '合计',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                }
            ],
            list: [
                {
                    label: '数据',
                    prop: 'appName'
                },
                {
                    label: '数据',
                    prop: 'excessive'
                },
                {
                    label: '昨天',
                    prop: 'yesterdayPendingReview'
                },
                {
                    label: '今天',
                    prop: 'newAddedToday'
                },
                {
                    label: '明天',
                    prop: 'currentAuditCirculation'
                },
                {
                    label: '后天',
                    prop: 'rejectionVolumeToday'
                },
                {
                    label: '大后天',
                    prop: 'remainingQuantityReview'
                }
            ]
        },
        {
            title: '出租车',
            columnList: [
                {
                    appName: '出租车1',
                    excessive: '出租车1',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '出租车2',
                    excessive: '出租车2',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                },
                {
                    appName: '出租车3',
                    excessive: '出租车3',
                    yesterdayPendingReview: 20,
                    newAddedToday: 30,
                    currentAuditCirculation: 40,
                    rejectionVolumeToday: 50,
                    remainingQuantityReview: 60
                }
            ],
            list: [
                {
                    label: '数据',
                    prop: 'appName'
                },
                {
                    label: '数据',
                    prop: 'excessive'
                },
                {
                    label: '昨天',
                    prop: 'yesterdayPendingReview'
                },
                {
                    label: '今天',
                    prop: 'newAddedToday'
                },
                {
                    label: '明天',
                    prop: 'currentAuditCirculation'
                },
                {
                    label: '后天',
                    prop: 'rejectionVolumeToday'
                },
                {
                    label: '大后天',
                    prop: 'remainingQuantityReview'
                }
            ]
        }
    ]
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338

代码实现

<div v-for="(table, idx) in tableData">
                <el-table
                    size="medium"
                    :data="table.columnList"
                    v-tableFit
                    highlight-current-row
                    :stripe="false"
                    ref="table"
                    id="table"
                    v-if="!loading"
                    v-loading="loading"
                    :span-method="
                        param => {
                            return tableSpanMethod(param, idx)
                        }
                    "
                    :header-cell-style="handerMethod"
                    :row-class-name="tableRowClassName"
                >
                    <el-table-column
                        v-for="(column, columIndex) in table.list.slice(0, 2)"
                        :key="columIndex"
                        :prop="column.prop"
                        :label="column.label"
                        align="center"
                        :index="columIndex"
                        show-overflow-tooltip
                    >
                        <template slot-scope="{ row, $index }">
                            <span>{{ row[column.prop] }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column :label="table.title" align="center">
                        <el-table-column
                            v-for="(column, columIndex) in table.list.slice(2, 7)"
                            :key="columIndex"
                            :prop="column.prop"
                            :label="column.label"
                            align="center"
                            :index="columIndex"
                            show-overflow-tooltip
                        >
                            <template slot-scope="{ row, $index }">
                                <span>{{ row[column.prop] }}</span>
                            </template>
                        </el-table-column>
                    </el-table-column>
                </el-table>
            </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
//导入mock数据
import * as dict from './index.js'
data() {
        return {
            loading: false,
            spanArr0: dict.columnVarsData.spanArr0,
            spanArr1: dict.columnVarsData.spanArr1,
            spanArr2: dict.columnVarsData.spanArr2,
            tableData: dict.columnVarsData.tableData
        }
    }

methods: {
	//隐藏表头
        handerMethod({ row, column, rowIndex, columnIndex }) {
            if (row[0].level == 1) {
                //这里有个非常坑的bug 必须是row[0]=0 row[1]=2才会生效
                row[0].colSpan = 0
                row[1].colSpan = 2
                if (columnIndex === 0) {
                    return { display: 'none' }
                }
            }
        },
        //单元格合并
        tableSpanMethod({ row, column, rowIndex, columnIndex }, idx) {
            const span = `spanArr${idx}`
            const spanArr = this[span]
            for (let i = 0; i < spanArr.length; i++) {
                //划分出需合并的每一个区域(spanArr[i])
                if (
                    columnIndex >= spanArr[i].columnIndex &&
                    columnIndex <= spanArr[i].columnIndex + spanArr[i].colspan - 1 &&
                    rowIndex >= spanArr[i].rowIndex &&
                    rowIndex <= spanArr[i].rowIndex + spanArr[i].rowspan - 1
                ) {
                    // 保留展示的单元格,合并单元格都为向右与向下延伸
                    if (
                        columnIndex === spanArr[i].columnIndex &&
                        rowIndex === spanArr[i].rowIndex
                    ) {
                        return {
                            rowspan: spanArr[i].rowspan,
                            colspan: spanArr[i].colspan
                        }
                    } else {
                        //删除冗余单元格
                        return {
                            rowspan: 0,
                            colspan: 0
                        }
                    }
                }
            }
        },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

效果

在这里插入图片描述
--------------------------------------------------------- 手动分割线 -----------------------------------------------

目前spanArr0、spanArr1、spanArr2是写死的,如果后端返回的输入不固定的话,那个还要挨个去改,所以手动写个方法。可自行优化方法

data() {
        return {
            loading: false,
            spanArr0: [],
            spanArr1: [],
            spanArr2: [],
            tableData: dict.columnVarsData.tableData,
        }
    }
created() {
        this.spanArr0 = this.handleList(this.tableData[0].columnList)
        this.spanArr1 = this.handleList(this.tableData[1].columnList)
        this.spanArr2 = this.handleList(this.tableData[2].columnList)
},
methods: {
	//处理数据行列单元格
        handleList(list) {
            let name = ''
            let arr = []
            let ownidx = 0
            for (let i = 0; i < list.length; i++) {
                //如果这两个字段相同取出行坐标放在数组里
                if (list[i].appName == list[i].excessive) {
                    let rowObj = {
                        rowIndex: i,
                        columnIndex: 0,
                        rowspan: 1,
                        colspan: 2
                    }
                    arr.push(rowObj)
                } else {
                    list[i]['count'] = 0
                    name = list[i].appName
                    //如果数据不同看数组里appName相同的有几条数据
                    const arrList = this.countKeywords(list, name)
                    let idx = arrList.findIndex(item => item.appName === name)
                    ownidx = idx
                    let colObj = {
                        rowIndex: idx,
                        columnIndex: 0,
                        rowspan: arrList[idx]['count'],
                        colspan: 1
                    }
                    arr.push(colObj)
                }
            }
            arr = this.countIdxwords(arr, ownidx)

            return arr
        },
        //获取appName相同的数据
        countKeywords(array, appName) {
            for (let j = 0; j < array.length; j++) {
                let k = 'appName'
                if (array[j][k] != appName) array[j]['count'] = 1
                else array[j]['count'] += 1
            }
            return array
        },
        //最后处理数据,合并行
        countIdxwords(arr, idx) {
            //  第一步,去重
            var hash = []
            for (var i = 0; i < arr.length; i++) {
                for (var j = i + 1; j < arr.length; j++) {
                    if (arr[i].rowIndex === arr[j].rowIndex) {
                        ++i
                        j = i
                    }
                }
                arr[i].num = 0
                hash.push(arr[i])
            }
            // 第二步,统计重复个数
            hash.forEach(item => {
                arr.forEach(dd => {
                    if (item.rowIndex === dd.rowIndex) {
                        item.num++
                    }
                })
            })
            console.log(hash, '===>hash')
            return hash
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

看一下改好的效果

没啥变化
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/101082
推荐阅读
相关标签
  

闽ICP备14008679号