使用element-ui实现行合并过程

 更新时间:2022年08月01日 09:37:50   作者:小白变怪兽  
这篇文章主要介绍了使用element-ui实现行合并过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

element-ui实现行合并过程

目标样式:

首先先来看下我们拿到的返回数据:

tableData: [
        {
          productType: "纺织品",
          price: 123,
          productName: '男装上衣',
          amount: 20,
          operate_number: "20180831142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "纺织品",
          price: 123,
          productName: '男装裤子',
          amount: 20,
          operate_number: "20180831142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "饮料",
          price: 123,
          productName: '康师傅冰红茶',
          amount: 20,
          operate_number: "20180823142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "纺织品",
          price: 223,
          productName: '男装裤子',
          amount: 10,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小王"
        },{
          productType: "绸缎",
          price: 888,
          productName: '旗袍',
          amount: 200,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "绸缎",
          price: 123,
          productName: '席子',
          amount: 20,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },
      ]

我们需要将返回的数据按照该字段(operate_number)进行处理。—— 将相同operate_number的信息的索引进行对应存储。

getOrderNumber() {
        let OrderObj = {}
        this.tableData.forEach((element, index) => {
            element.rowIndex = index
            if (OrderObj[element.operate_number]) {
              OrderObj[element.operate_number].push(index)
            } else {
              OrderObj[element.operate_number] = []
              OrderObj[element.operate_number].push(index)
            }
        })
        // 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
        for (let k in OrderObj) {
          if (OrderObj[k].length > 1) {
            this.OrderIndexArr.push(OrderObj[k])
          }
        }
      },

然后根据我们页面展示需要, 控制哪一些列上的数据是需要进行展示的。

 // 合并单元格
      objectSpanMethod({row,column,rowIndex,columnIndex}) {
        if (columnIndex === 0 || columnIndex === 3 || columnIndex === 4) {
          for (let i = 0; i < this.OrderIndexArr.length; i++) {
            let element = this.OrderIndexArr[i]
            for (let j = 0; j < element.length; j++) {
              let item = element[j]
              if (rowIndex == item) {
                if (j == 0) {
                  return {
                    rowspan: element.length,
                    colspan: 1
                  }
                } else if (j != 0) {
                  return {
                    rowspan: 0,
                    colspan: 0
                  }
                }
              }
            }
          }
        }
      },

经过上述操作之后我们就能成功的绘制出如图所需要的效果了。##完整代码后面附上##

存在问题

不过这样的话会存在一个显示问题。就是当我们的鼠标滑过的时候,显示效果不佳,如下图所示:

这里写图片描述

合并后的一行数据,滑过的时候效果就不对了,接下来我们就来解决一下这个问题,让效果能达到如下图所示:

这里写图片描述

关键词##: cell-mouse-enter cell-mouse-leave cell-class-name

通过触发鼠标划入,划出的时候单元格的样式:

// 单元格样式
tableRowClassName({row,rowIndex}) {
        let arr = this.hoverOrderArr
        for (let i = 0; i < arr.length; i++) {
          if (rowIndex == arr[i]) {
            return 'hovered-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 = [];
      }

附上完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>element-ui实现合并单元格效果</title>
  <link href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="external nofollow"  rel="stylesheet">
  <style>
    .el-table .hovered-row {
      background: #f5f7fa;
    }
  </style>
</head>
<body>
  <div id="app">
      <el-table ref="multipleTable" border :span-method="objectSpanMethod" :cell-class-name="tableRowClassName"
        @cell-mouse-leave="cellMouseLeave"  @cell-mouse-enter="cellMouseEnter" :data="tableData" style="width: 80%;margin:0 auto;">
        <el-table-column label="商品类别" align="center">
          <template slot-scope="scope" width="160">
              <div>{{scope.row.productType}}</div>
          </template>
        </el-table-column>
        <el-table-column label="商品价格" align="center">
          <template slot-scope="scope">
            <p>{{scope.row.price}}</p>
          </template>
        </el-table-column>
        <el-table-column label="商品名称" width="180px" align="center">
          <template slot-scope="scope">
            <p>{{scope.row.productName}}</p>
          </template>
        </el-table-column>
        <el-table-column label="操作人员" align="center">
          <template slot-scope="scope">
            <p>{{scope.row.operator}}</p>
          </template>
        </el-table-column>
        <el-table-column prop="updateTime" label="更新时间" align="center">
        </el-table-column>
      </el-table>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      tableData: [
        {
          productType: "纺织品",
          price: 123,
          productName: '男装上衣',
          amount: 20,
          operate_number: "20180831142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "纺织品",
          price: 123,
          productName: '男装裤子',
          amount: 20,
          operate_number: "20180831142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "饮料",
          price: 123,
          productName: '康师傅冰红茶',
          amount: 20,
          operate_number: "20180823142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "纺织品",
          price: 223,
          productName: '男装裤子',
          amount: 10,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小王"
        },{
          productType: "绸缎",
          price: 888,
          productName: '旗袍',
          amount: 200,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },{
          productType: "绸缎",
          price: 123,
          productName: '席子',
          amount: 20,
          operate_number: "20180821142020",
          price: "36.00",
          updateTime: "2018-08-31",
          operator: "小吴"
        },
      ],
      rowIndex: '-1',
      OrderIndexArr: [],
      hoverOrderArr: []
    },
    mounted() {
      this.getOrderNumber()
    },
    methods: {
      // 获取相同编号的数组
      getOrderNumber() {
        let OrderObj = {}
        this.tableData.forEach((element, index) => {
            element.rowIndex = index
            if (OrderObj[element.operate_number]) {
              OrderObj[element.operate_number].push(index)
            } else {
              OrderObj[element.operate_number] = []
              OrderObj[element.operate_number].push(index)
            }
        })
        // 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
        for (let k in OrderObj) {
          if (OrderObj[k].length > 1) {
            this.OrderIndexArr.push(OrderObj[k])
          }
        }
      },
      // 合并单元格
      objectSpanMethod({row,column,rowIndex,columnIndex}) {
        if (columnIndex === 0 || columnIndex === 3 || columnIndex === 4) {
          for (let i = 0; i < this.OrderIndexArr.length; i++) {
            let element = this.OrderIndexArr[i]
            for (let j = 0; j < element.length; j++) {
              let item = element[j]
              if (rowIndex == item) {
                if (j == 0) {
                  return {
                    rowspan: element.length,
                    colspan: 1
                  }
                } else if (j != 0) {
                  return {
                    rowspan: 0,
                    colspan: 0
                  }
                }
              }
            }
          }
        }
      },
      tableRowClassName({row,rowIndex}) {
        let arr = this.hoverOrderArr
        for (let i = 0; i < arr.length; i++) {
          if (rowIndex == arr[i]) {
            return 'hovered-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 = [];
      }
    }
  })
</script>
</html>

element-ui合并单元格行处理方法

在平时开发过程中经常涉及到行、列单元格的合并,本文记录LZ使用方式,只涉及到行的合并(场景较多),列也可同理而得

获取合并规则

 /**
   * 合并单元格
   * @param tableData  table数据 []
   * @param spans      待合并 property  
   * eg:[{key:'country'},{key:'year',rely:'country'}], rely表依赖,是否依赖前置列
   * @returns {{}}
   */
  getMergeSpan(tableData,spans){
    let rowMerge = {},obj = {}
    for(let i = 0;i<spans.length;i++){
      let property = spans[i].key
      let rely = spans[i].rely
      let total = 1 , start = 0
      tableData.forEach((item,index)=>{
        let nextRow = tableData[index+1] || {}
        let isComRely =  rely ? item[rely] === nextRow[rely] : true
        if(item[property] === nextRow[property] && isComRely){
          total ++
        }else{
          obj[start] = total
          start = index + 1
          total = 1
        }
      })
      rowMerge[property] = obj
      obj = {}
    }
    return rowMerge
  },

elemen-ui  span-method 合并方式

   /**
   * element-ui 合并方法
   * @param row 行 数据
   * @param column 列信息
   * @param rowIndex 行号
   * @param columnIndex 列号
   * @returns {(*|number)[]|number[]}
   */
  tableMergeMethod({ row, column, rowIndex, columnIndex }) {
    if(columnIndex === 0){  //tip: 列位置 须根据el-table-column获取
      let total = this.tableMerge['country'][rowIndex]
      if(total){
        return [total,1]
      }else {
        return [0,0]
      }
    }
    if(columnIndex === 1){
      let total = this.tableMerge['year'][rowIndex] // tableMerge:通过getMergeSpan获取的规则
      if(total){
        return [total,1]
      }else {
        return [0,0]
      }
    }
  },

eg:

this.tableMerge = getMergeSpan(this.tableData,[{key:'country'},{key:'year',rely:'country'}])

合并效果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 通过源码分析Vue的双向数据绑定详解

    通过源码分析Vue的双向数据绑定详解

    使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,下面这篇文章通过源码主要分析了Vue的双向数据绑定,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • tdesign和vue的子组件关闭是父组件执行方法

    tdesign和vue的子组件关闭是父组件执行方法

    这篇文章主要介绍了tdesign和vue的子组件关闭是父组件执行方法,需要的朋友可以参考下
    2006-06-06
  • vue学习笔记之Vue中css动画原理简单示例

    vue学习笔记之Vue中css动画原理简单示例

    这篇文章主要介绍了vue学习笔记之Vue中css动画原理,结合简单实例形式分析了Vue中css样式变换动画效果实现原理与相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • Vue项目识别不到@别名问题及解决

    Vue项目识别不到@别名问题及解决

    这篇文章主要介绍了Vue项目识别不到@别名问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue中数组加Key方式

    vue中数组加Key方式

    这篇文章主要介绍了vue中数组加Key方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • vue3+vite2实现动态绑定图片的优雅解决方案

    vue3+vite2实现动态绑定图片的优雅解决方案

    这篇文章主要为大家详细介绍了vue3+vite2实现动态绑定图片的优雅解决方案,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-08-08
  • 利用vue.js实现被选中状态的改变方法

    利用vue.js实现被选中状态的改变方法

    下面小编就为大家分享一篇利用vue.js实现被选中状态的改变方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • vue里的axios如何获取本地json数据

    vue里的axios如何获取本地json数据

    这篇文章主要介绍了vue里的axios如何获取本地json数据,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Vue两个版本的区别和使用方法(更深层次了解)

    Vue两个版本的区别和使用方法(更深层次了解)

    在我们使用 vue时,我们可以引用两个不同版本的 Vue,分别是 Vue完整版(vue.js)和 Vue(vue.runtime.js )非完整版,那么它们的区别是什么呢,今天我们就来分析下这两个不同版本之间的区别,一起看看吧
    2020-02-02
  • 详解vue或uni-app的跨域问题解决方案

    详解vue或uni-app的跨域问题解决方案

    这篇文章主要介绍了详解vue或uni-app的跨域问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论