zoukankan      html  css  js  c++  java
  • 由element-ui的table引发的系列问题---单元格合并hover样式

    参考文章

    说明:

    由于本文中使用的函数直接复制过来改了改,所有总归会是差不多的,但是也只是更方便两者进行对照来使得读者更加容易明白一些细节上的问题。

    在我们按照需求把相应的数据进行合并操作后,新的问题也随之而来,那就是在单元格的hover样式上依旧不是那么尽人意。

    如下图所示,鼠标经过首行的时候,无法将具有合并的行进行全部高亮,而是之后被合并的行具有高亮显示

     再来看下官方示例,也是如此:

    预期效果:

     

    想要解决这个问题,直接借助官方提供的一个属性( row-class-name )和两个事件( cell-mouse-enter、cell-mouse-leave )

    属性介绍如下图所示:

     

    以下是一大坨的代码,请查收。

    <template>
      <div>
        <el-table
          :data="tableData"
          :span-method="spanMethod"
          :row-class-name="tableRowClassName"
          border
          style=" 100%"
          @cell-mouse-enter="cellMouseEnter"
          @cell-mouse-leave="cellMouseLeave"
          >
          <el-table-column
            prop="id"
            label="ID"
            width="180">
          </el-table-column>
          <el-table-column
            prop="name"
            label="姓名">
          </el-table-column>
          <el-table-column
            prop="amount1"
            label="数值 1">
          </el-table-column>
          <el-table-column
            prop="amount2"
            label="数值 2">
          </el-table-column>
          <el-table-column
            prop="amount3"
            label="数值 3">
          </el-table-column>
        </el-table>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          tableData: [
            {
              id: '12987122',
              name: '王小虎',
              amount1: '234',
              amount2: '3.2',
              amount3: 10
            }, {
              id: '1298712',
              name: '王小虎',
              amount1: '165',
              amount2: '4.43',
              amount3: 12
            }, {
              id: '12987124',
              name: '王小二',
              amount1: '324',
              amount2: '1.9',
              amount3: 9
            }, {
              id: '12987125',
              name: '张三',
              amount1: '621',
              amount2: '2.2',
              amount3: 17
            }, {
              id: '12987125',
              name: '张三',
              amount1: '539',
              amount2: '4.1',
              amount3: 15
            }
          ],
          spanArr: [],
          position: 0,
          needSpan: ['id', 'name'], // 需要合并的属性
          spanArrObj: {
            id: [],
            name: []
          },
          rowIndex: '-1',
          OrderIndexArr: [],
          hoverOrderArr: []
        }
      },
      created () {
        this.getSpanArr()
      },
      watch: {
        tableData () {
          this.getOrderNumber()
        }
      },
      mounted () {
        this.getOrderNumber()
      },
      methods: {
        // 合并行方法
        spanMethod ({ row, column, rowIndex, columnIndex }) {
          if (columnIndex === 0) {
            const _row = this.spanArrObj['id'][rowIndex]
            const _col = _row > 0 ? 1 : 0
            return {
              rowspan: _row,
              colspan: _col
            }
          }
          if (columnIndex === 1) {
            const _row = this.spanArrObj['name'][rowIndex]
            const _col = _row > 0 ? 1 : 0
            return {
              rowspan: _row,
              colspan: _col
            }
          }
        },
        // 获取合并行参数(数组)
        rowspan (prop, first = 'id') {
          // this.position = 0
          // this.spanArrObj = []
          this.tableData.forEach((item, index) => {
            if (index === 0) {
              this.spanArrObj[prop].push(1)
              this.position = 0
            } else {
              if (this.tableData[index][first] === this.tableData[index - 1][first] && this.tableData[index][prop] === this.tableData[index - 1][prop]) {
                this.spanArrObj[prop][this.position] += 1
                this.spanArrObj[prop].push(0)
              } else {
                this.spanArrObj[prop].push(1)
                this.position = index
              }
            }
          })
        },
        getSpanArr () {
          this.needSpan.forEach(item => {
            this.rowspan(item)
          })
        },
        // editRow () {
        //   this.$forceUpdate() // vue提供的方法 - 强制刷新视图
        // },
        tableRowClassName ({ row, rowIndex }) {
          var arr = this.hoverOrderArr
          for (var i = 0; i < arr.length; i++) {
            if (rowIndex === arr[i]) {
              return 'success-row'
            }
          }
        },
    
        cellMouseEnter (row, column, cell, event) {
          this.rowIndex = row.rowIndex
          this.hoverOrderArr = []
          this.OrderIndexArr.forEach((element) => {
            if (element.indexOf(this.rowIndex) >= 0) {
              this.hoverOrderArr = element
            }
          })
        },
    
        cellMouseLeave (row, column, cell, event) {
          this.rowIndex = '-1'
          this.hoverOrderArr = []
        },
    
        // 获取相同编号的数组
        getOrderNumber () {
          var OrderObj = {}
          this.tableData.forEach((element, index) => {
            element.rowIndex = index
            if (OrderObj[element.id]) {
              OrderObj[element.id].push(index)
            } else {
              OrderObj[element.id] = []
              OrderObj[element.id].push(index)
            }
          })
    
          for (var k in OrderObj) {
            if (OrderObj[k].length > 1) {
              this.OrderIndexArr.push(OrderObj[k])
            }
          }
        }
      }
    }
    </script>
    
    <style lang="less" scoped>
      /deep/.el-table .success-row {
        background: #f5f7fa;
      }
    </style>

    由于太懒了,具体细节就不多说了,就大概总结一下:

    ①在拿到这个表格的数据(tableData)的时候,根据合并项的参照数据(id)进行去重,然后塞入一个rowIndex作为判断

    当前鼠标hover的行是否与其它行存在合并关系,getOrderNumber做的就是这个工作,因为这里的数据是写死的,所以

    我在mounted中多调用了一次这个方法,实际开发中,则只需要监听tableData的变化来生成判断依据rowIndex即可。

    ②通过上述方法塞入判断依据后再通过鼠标的移入移出table事件来进行交互(判断当前hover中的行是否与其它行存在合并关系,并将有关系的这几行放在hoverOrderArr这个数组里),也就是这俩事件( cell-mouse-enter、cell-mouse-leave )

    ③最后再通过( row-class-name )这个属性所对应的函去遍历第二步中得到的数组,以确定是否要给某行加上hover样式的类名。

  • 相关阅读:
    显卡关键词
    为照顾IE6尽量不要margin和padding
    如何保证一个类只有一个实例(1)
    显示列表(display list)
    AutoCAD2007与Office2007冲突
    虚函数(1)
    字符串对象的属性
    细读cow.osg
    常量折叠(const folding)与复写传播 (copy propagation)
    .NET Framework 3.5 sp1离线安装
  • 原文地址:https://www.cnblogs.com/ViavaCos/p/12855864.html
Copyright © 2011-2022 走看看