el-table合并行,并添加hover样式

5,387 阅读3分钟
  • 记录一下 el-table 的踩坑经历~
  • element-ui 官方文档给出了基础的 el-table的合并行的例子,但是hover样式是存在问题的,看了各种解决方案,最终整理出一套相对简单的解决方案,希望对大家有帮助~

先看下整体效果吧

  • 这个是一个前三列需要做行合并的一个表格,我的列表数据是酱紫的~
tableData: [
  { prnm: '坝顶', mtnm: '变形监测', content: '水平位移', ptcd: 'PL2', ptnm: '垂线坐标仪', mstm: '1.02mm', val: '2021-2-5', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '变形监测', content: '水平位移', ptcd: 'PL2', ptnm: '倒垂', mstm: '1.02mm', val: '2021-2-13', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '变形监测', content: '水平位移', ptcd: 'PL3', ptnm: '正垂', mstm: '1.02mm', val: '2021-2-14', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '变形监测', content: '垂直位移', ptcd: 'PL4', ptnm: '类型1', mstm: '1.02mm', val: '2021-2-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '变形监测', content: '垂直位移', ptcd: 'PL5', ptnm: '类型2', mstm: '1.02mm', val: '2021-2-8', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '渗流监测', content: '渗流量', ptcd: 'PL6', ptnm: '类型3', mstm: '1.02mm', val: '2021-2-10', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '坝顶', mtnm: '环境量监测', content: '上下游水位', ptcd: 'PL7', ptnm: '类型4', mstm: '1.02mm', val: '2021-12-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '1#垛', mtnm: '变形监测', content: '水平位移', ptcd: '1', ptnm: '1', mstm: '1.02mm', val: '2021-2-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '1#垛', mtnm: '变形监测', content: '2', ptcd: '2', ptnm: '2', mstm: '1.02mm', val: '2021-5-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '2#垛', mtnm: '渗流监测', content: '3', ptcd: '3', ptnm: '3', mstm: '1.02mm', val: '2021-4-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' },
  { prnm: '2#垛', mtnm: '渗流监测', content: '4', ptcd: '4', ptnm: '4', mstm: '1.02mm', val: '2021-3-1', minValue: '0.00', maxValue: '2.00', pdfUrl: '' }
]
  • 把前三列字段相同的去做合并 (完整代码在codepen,链接放在最下面~)
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
    // console.log(row, column, rowIndex, columnIndex)
    switch (columnIndex) {
        case 0: //监测部位
            return this.setTableRowCol(row, rowIndex, ['prnm'])
        case 1: //监测项目
            return this.setTableRowCol(row, rowIndex, ['prnm', 'mtnm'])
        case 2: //监测内容
            return this.setTableRowCol(row, rowIndex, ['prnm', 'mtnm', 'content'])
    }
},
setTableRowCol(row, rowIndex, keys) {
    let firstIndex = 0, rowspan = 1, colspan =1
    // 找到需要合并的行的下标
    firstIndex = this.tableData.findIndex(item => {
        return this.filterSameKeys(item, row, keys)
    })
    if (rowIndex === firstIndex) {
    	// 需要合并的行数
        rowspan = this.tableData.filter(item => {
            return this.filterSameKeys(item, row, keys)
        }).length
        colspan = 1
    } else { // 被合并的行需要设置成0
        rowspan = 0
        colspan = 0
    }
    // console.log(key, rowIndex, rowspan, colspan)
    return {
        rowspan,
        colspan
    }
},
// 根据keys数组所有字段去做合并
filterSameKeys(item, row, keys) {
    let flag = true
    keys.forEach(key => {
        flag = flag && item[key] === row[key]
    })
    return flag
},
  • 行合并就完成了~
  • 开始实现hover效果,由于第一、二、三列和当前鼠标移动到的cell不一定在同一行,所以需要给要高亮展示的第一、二、三列所在行添加class,加上背景颜色,就ok了~
  • 需要用到 el-table的 row-class-name、 cell-mouse-enter、 cell-mouse-leave,找到需要高亮的第一、二、三列所在行,分别加上class: first_row 、 second_row 、 third_row
// 鼠标移入时找到需要高亮的第一、二、三列所在行,也就是第一次出现的行
cellMouseEnter(row) {
    this.third_row = this.tableData.filter(item => {
        return this.filterSameKeys(item, row, ['prnm', 'mtnm', 'content'])
    })[0]
    this.second_row = this.tableData.filter(item => {
        return this.filterSameKeys(item, row, ['prnm', 'mtnm'])
    })[0]
    this.first_row = this.tableData.filter(item => {
        return this.filterSameKeys(item, row, ['prnm'])
    })[0]
},
// 鼠标移出
cellMouseLeave() {
    this.first_row = {}
    this.second_row = {}
    this.third_row = {}
},
// 设置行class
tableRowClassName({ row }) {
    let flag1 = this.first_row == row ? 'first_row' : ''
    let flag2 = this.second_row == row? 'second_row' : ''
    let flag3 = this.third_row == row? 'third_row' : ''
    return `${flag1} ${flag2} ${flag3}`
}
  • 最后就是样式了
.el-table {
    .first_row, .second_row, .third_row {
        td:nth-child(1) {
          background: #f5f7fa !important;
        }
    }
    // 第一列和第二列是同一行的情况   第二列和第三列是同一行的情况
    .first_row.second_row, .second_row.third_row {
        td:nth-child(2) {
          background: #f5f7fa !important;
        }
    }
    // 第一列、第二列和第三列是同一行的情况
    .first_row.second_row.third_row {
        td:nth-child(3) {
          background: #f5f7fa !important;
        }
    }
}

大功告成!