element-ui 使用span-method表格合并后hover样式的处理

在使用element表格合并后,发现鼠标只有移入第一个合并行时,合并的部分会高亮,移入其他行,不会高亮,这样效果看起来不是很好.查看了文档也没有直接的解决方法,就通过现有的方法处理了一下,解决了hover的问题
因为实际使用时,表格数据都是后台返回的,所以这里就只写一下后台动态返回的数据设置hover样式
 
以两层合并数据为例
 
因为表格合并的特性,合并后,只有这一个合并区域的第一行才有合并td元素,其他行是没有这个元素
所以在其他行鼠标移入时,需要给第一行的合并单元格增加背景色
 
element提供了单元格的鼠标移入移出事件.通过这个控制元素的样式添加
 
其他行需要存储这个合并区域的第一行索引,鼠标移入时,如果移入的不是第一行,就把这个索引取出来
// 单元格移入事件
  handleMouse (row, column, cell, event) {
    if (!row.typeIndex) { // 不符合合并行的条件手动加class
      // 只能给第一行加才有效, 把之前保存的第一行的索引存起来
      this.cellIndex = row.firstIndex
      // console.log(99, this.cellIndex, row.firstIndex)
      this.isCell = true
    }
  },

  // 单元格移除事件
  handleMouseLeve () {
    this.isCell = false
  },

 

设置样式,把表格的索引和取出来的索引对比,如果是第一行,就加上样式
// 设置行样式
  setCellClass ({row, column, rowIndex, columnIndex}) {
    // 给当前鼠标移入的合并行第一行加上样式名
    if (row.index === this.cellIndex) {
      return 'cellClass'
    }
  },
 
 样式设置中,你是第几列合并,就给第几个td增加背景色,我这里是第一列和第二列合并,就给这两列增加背景色

 

.el-table {
  // 两层合并的样式部分
  .cellClass {
    td:nth-child(1) {
      background-color: #f5f7fa;
    }
    td:nth-child(2) {
      background-color: #f5f7fa;
    }
  }
}

 

三层合并的思路也是一样,只是样式要分成两部分控制

完整代码: 这个代码是在之前一篇表格合并的博客代码基础上增加,标红部分是新增的代码

<template>
  <div style="padding:30px;">
    <h2>后台返回数据动态合并(根据后台返回的数据进行表格合并)</h2>
    <p>
      两层数据合并
    </p>
    <el-table
      :data="tableData2"
      :span-method="arraySpanMethod2"
      :row-class-name="isCell ? setCellClass : ''"
      border
      @cell-mouse-enter="handleMouse"
      @cell-mouse-leave="handleMouseLeve"
      style="width: 100%;"
    >
      <el-table-column
        prop="id"
        label="ID"
        width="180"
      />
      <el-table-column
        prop="region"
        label="地区"
      />
      <el-table-column
        prop="type"
        label="类型"
      />
    </el-table>
    <!-- 表格2 -->
    <p style="margin-top: 40px">
      三层数据合并
    </p>
    <el-table
      :data="tableData"
      :span-method="arraySpanMethod"
      :row-class-name="isCell2 ? setCellClass2 : ''"
      border
      @cell-mouse-enter="handleMouse2"
      @cell-mouse-leave="handleMouseLeve2"
      style="width: 100%"
    >
      <el-table-column
        prop="id"
        label="ID"
        width="180"
      />
      <el-table-column
        prop="region"
        label="地区"
      />
      <el-table-column
        prop="type"
        label="类型"
      />
      <el-table-column
        prop="name"
        label="产业"
      />
      <el-table-column
        prop="price"
        label="价格"
      />
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [],
      tableData2: [],
      cellIndex: null, // 两层合并的数据
      isCell: false,
      isCell2: false, // 三层合并的数据
      twoCellIndex: null,
      thirdCellIndex: null
    }
  },
  created() {
    this.getTable()
  },
  methods: {
    getTable() {
      const tableData = [{
        id: 1,
        region: '中国',
        type: [{
          sortName: '器械',
          sortList: [{
            name: '器械1',
            price: 7888
          }, {
            name: '器械2',
            price: 7888
          }]
        }, {
          sortName: '器械',
          sortList: [{
            name: '器械2',
            price: 67555
          }, {
            name: '器械3',
            price: 1233
          }]
        }, {
          sortName: '软件',
          sortList: [{
            name: '软件1',
            price: 5666
          }, {
            name: '软件2',
            price: 78885
          }, {
            name: '软件3',
            price: 10000
          }]
        }]
      }, {
        id: 2,
        region: '美国',
        type: [{
          sortName: '器械',
          sortList: [{
            name: '器械1',
            price: 2000
          }, {
            name: '器械2',
            price: 3333
          }]
        }, {
          sortName: '软件',
          sortList: [{
            name: '软件1',
            price: 23333
          }, {
            name: '软件2',
            price: 7000
          }]
        }]
      }, {
        id: 3,
        region: '加拿大',
        type: [{
          sortName: '器械',
          sortList: [{
            name: '器械1',
            price: 3000
          }]
        }]
      }]
      this.dealTable(tableData)
      this.dealTable(tableData, 2)
    },

    // 处理表格数据(level,表格合并的层级)
    dealTable(tableData, level = 3) {
      const getDate = [] // 存储新表格数据
      let a // id,地区需要合并的行是所有类型的长度
      let firstIndex = 0 // 储存需要设置hover背景色的单元行(两层)
      // let firstIndex2 = 0 // 储存需要设置hover背景色的单元行(三层)
      tableData.forEach((v, index) => {
        if (v.type && v.type.length) {
          a = 0
          v.type.forEach((subV, i, typeData) => {
            if (level === 2) { // 处理两层合并数据
              const obj = {
                id: v.id,
                region: v.region,
                type: subV.sortName
              }
              obj.index = getDate.length
              if (i === 0) {
                obj.typeIndex = typeData.length
                firstIndex = obj.index
              } else {
                obj.firstIndex = firstIndex // 存储第一行索引
              }
              getDate.push(obj)
            } else if (subV.sortList && subV.sortList.length) {
              subV.sortList.forEach((ss, k, data) => {
                const obj = {
                  id: v.id,
                  region: v.region,
                  type: subV.sortName,
                  name: ss.name,
                  price: ss.price
                }
                obj.index = getDate.length
                if (k === 0) {
                  obj.typeIndex = data.length
                  firstIndex = obj.index
                } else {
                  obj.firstIndex = firstIndex // 存储两层合并的第一行索引
                }
                getDate.push(obj)
                if (k === data.length - 1) {
                  a += data.length // 把所有类型下面的数据长度相加
                  if (i === typeData.length - 1) {
                    getDate[getDate.length - a ].nameIndex = a
                    // 存储三层合并的第一行索引
                    for (let i = getDate.length - a + 1; i < getDate.length; i++) {
                      getDate[i].firstIndex2 = getDate.length - a
                    }
                  }
                }
              })
            }
          })
        }
      })

      if (level === 2) {
        this.tableData2 = getDate
      } else {
        this.tableData = getDate
      }
      console.log(getDate)
    },

    // 表格合并方法(三层数据)
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 || columnIndex === 1) {
        if (row.nameIndex) { // 如果有值,说明需要合并
          return [row.nameIndex, 1]
        } else return [0, 0]
      }
      if (columnIndex === 2) {
        if (row.typeIndex) {
          return [row.typeIndex, 1]
        } else return [0, 0]
      }
    },
    // 表格合并方法(两层数据)
    arraySpanMethod2({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 || columnIndex === 1) {
        if (row.typeIndex) { // 如果有值,说明需要合并
          return [row.typeIndex, 1]
        } else return [0, 0]
      }
    },

    /** ------------------两层合并鼠标移入----------------- */
    // 单元格移入事件
    handleMouse (row, column, cell, event) {
      if (!row.typeIndex) { // 不符合合并行的条件手动加class
        // 只能给第一行加才有效, 把之前保存的第一行的索引存起来
        this.cellIndex = row.firstIndex
        // console.log(99, this.cellIndex, row.firstIndex)
        this.isCell = true
      }
    },

    // 单元格移除事件
    handleMouseLeve () {
      this.isCell = false
    },

    // 设置行样式
    setCellClass ({row, column, rowIndex, columnIndex}) {
      // 给当前鼠标移入的合并行第一行加上样式名
      if (row.index === this.cellIndex) {
        return 'cellClass'
      }
    },
    /** ----------------------end----------------------------- */

    /** ------------------三层合并鼠标移入----------------- */
    // 单元格移入事件
    handleMouse2 (row, column, cell, event) {
      if (!row.nameIndex) { // 不符合合并行的条件手动加class
        // 只能给第一行加才有效, 把之前保存的第一行的索引存起来
        this.twoCellIndex = row.firstIndex
        this.thirdCellIndex = row.firstIndex2
        this.isCell2 = true
      }
    },

    // 单元格移除事件
    handleMouseLeve2 () {
      this.isCell2 = false
    },

    // 设置行样式
    setCellClass2 ({row, column, rowIndex, columnIndex}) {
      // 给当前鼠标移入的合并行第一行加上样式名
      let cssName = ''
      if (row.index === this.twoCellIndex) { // 两层合并的行添加样式
        cssName = 'twoCellClass'
      }
      if (row.index === this.thirdCellIndex) { // 三层合并的行添加样式
        cssName += ' thirdCellClass'
      }
      return cssName
    }
  }
}
</script>

<style lang="less">
.el-table {
  // 两层合并的样式部分
  .cellClass {
    td:nth-child(1) {
      background-color: #f5f7fa;
    }
    td:nth-child(2) {
      background-color: #f5f7fa;
    }
  }

  // 三层合并的样式部分
  .twoCellClass {
    td:nth-child(1) {
      background-color: #f5f7fa;
    }
    &.thirdCellClass {
       td:nth-child(3) {
        background-color: #f5f7fa;
      }
    }
  }
  .thirdCellClass {
    td:nth-child(1) {
      background-color: #f5f7fa;
    }
    td:nth-child(2) {
      background-color: #f5f7fa;
    }
  }
}
</style>

 

处理后效果

处理之后,每一行移入都有高亮效果.方法对不同数据没有通用型性,只是一种解决思路,对于不同的合并条件要不同处理.大致思想就是在移入不符合合并行的时候给合并的第一行添加样式,必须要给第一行添加,第一行才有控制合并部分的元素.
如果有更简单的处理方法,也希望留言告知
 
posted @ 2019-03-04 11:58  潇湘羽西  阅读(7160)  评论(1编辑  收藏  举报