el-table 行合并的实现示例

目录
  • 示例一:单个表格
  • 示例二:循环表格

页面实现行合并的情况还是比较常见的,但实现起来却有一点点难。官网的例子有,不过人家的合并逻辑是从第一行开始两行两行合并,不能根据数据动态合并,感觉参考意义不太大。实际需求一般都是根据表数据动态来进行合并的,也会有更复杂的情况,比如循环表格的。

以下的例子中,表格数据是放在页面的假数据,hbxh 值相同时,表示需要合并

示例一:单个表格

单个表格的比较简单,知道合并方法的使用基本就好弄了

<template>
  <div>
    <el-form
      ref="testForm"
      :model="testForm"
      style="height: 600px;"
    >
      <el-row
        style="padding: 10px"
      >
        <el-table
          :data="testForm.tableData"
          :span-method="colSpanMethod"
          border
          style="width: 100%;"
        >
          <el-table-column prop="hbxh" label="合并序号" width="100" />
          <el-table-column prop="name" label="姓名" width="180" />
          <el-table-column prop="address" label="地址" />
        </el-table>
      </el-row>
    </el-form>
  </div>
</template>

<script>

export default {
  data() {
    return {
      spanArr: [], // 用于存放每一行记录的合并数
      testForm: {
        tableData: [
          {
            hbxh: '1',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            hbxh: '2',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            hbxh: '2',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            hbxh: '3',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }, {
            hbxh: '4',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }, {
            hbxh: '4',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }, {
            hbxh: '4',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }
        ] // 测试数据
      },
    }
  },
  created() {
    this.getSpanArr(this.testForm.tableData)
  },
  methods: {
    getSpanArr(data) {
      // data就是我们从后台拿到的数据
      for (var i = 0; i < data.length; i++) {
        if (i === 0) {
          this.spanArr.push(1);
          this.pos = 0;
        } else {
          // 判断当前对象的指定属性值与上一个对象的指定属性值是否相等
          if (data[i].hbxh === data[i - 1].hbxh) {
            this.spanArr[this.pos] += 1;
            this.spanArr.push(0);
          } else {
            this.spanArr.push(1);
            this.pos = i;
          }
        }
      }
    },
    colSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 || columnIndex === 2) {
        const _row = this.spanArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        console.log(`rowspan:${_row} colspan:${_col}`);
        return {
          // [0,0] 表示这一行不显示, [2,1]表示行的合并数
          rowspan: _row,
          colspan: _col
        };
      }
    }
  }

}
</script>

效果:

示例二:循环表格

循环表格时,需要在表的每行数据传入一个值,代表是第几个表格,方便合并方法使用

<template>
  <div>
    <el-form
      ref="testForm"
      :model="testForm"
      style="height: 600px;"
    >
      <el-row
        v-for="(item, index) in testForm.tableList"
        :key="index"
        style="padding: 10px"
      >
        <el-table
          :data="item"
          :span-method="colSpanMethod"
          border
          style="width: 100%; margin-bottom: 20px;"
        >
          <el-table-column prop="hbxh" label="合并序号" width="100" />
          <el-table-column prop="name" label="姓名" width="180" />
          <el-table-column prop="address" label="地址" />
        </el-table>
      </el-row>
    </el-form>
  </div>
</template>

<script>

export default {
  data() {
    return {
      spanArr: [], // 用于存放每一行记录的合并数
      testForm: {
        tableList: [
          [
            {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄',
              tbIndex: 0
            }, {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1517 弄',
              tbIndex: 0
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄',
              tbIndex: 0
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 0
            }
          ],
          [
            {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄',
              tbIndex: 1
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1517 弄',
              tbIndex: 1
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄',
              tbIndex: 1
            }, {
              hbxh: '3',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }
          ]
        ] // 测试数据
      },
    }
  },
  created() {
    this.getSpanArr(this.testForm.tableList)
  },
  methods: {
    getSpanArr(data) {
      // 用一个对象数组来存放每个表中每一行记录的合并数
      for (let m = 0, n = data.length; m < n; m++) {
        this.spanArr.push({
          tbArr: []
        });
      }
      for (let i = 0, l = data.length; i < l; i++) {
        let contactDot = 0; // 记录开始合并的行索引
        data[i].forEach((item, index) => {
          item.index = index
          if (index === 0) {
            this.spanArr[i].tbArr.push(1);
          } else {
            // 判断当前对象的指定属性值与上一个对象的指定属性值是否相等
            if (item.hbxh === data[i][index - 1].hbxh) {
              this.spanArr[i].tbArr[contactDot] += 1;
              this.spanArr[i].tbArr.push(0);
            } else {
              this.spanArr[i].tbArr.push(1);
              contactDot = index;
            }
          }
        })
      }
      console.log('==========this.spanArr==========')
      console.log(this.spanArr)
      /* [
        [2, 0, 2, 0],
        [1, 2, 0, 1, 3, 0, 0]
      ] */
    },
    colSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 2) {
        const _row = this.spanArr[row.tbIndex].tbArr[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          // [0,0] 表示这一行不显示, [2,1]表示行的合并数
          rowspan: _row,
          colspan: _col
        };
      }
    }
  }

}
</script>

有循环的需求时,数据结构会比较复杂,需要耐心理清数据之间的关系

效果:

合并的关键主要就是要准确计算出每行记录的合并数,计算逻辑可能每个人会想得不太一样,以上的栗子仅代表一种实现方式,不同方式的朋友可以留言讨论

>>>>>>>>>今天又发现了一种新的逻辑>>>>>>>>>>>>>(2021-11-29)

<template>
  <div>
    <el-form
      ref="testForm"
      :model="testForm"
      style="height: 600px;"
    >
      <el-row
        v-for="(item, index) in testForm.tableList"
        :key="index"
        style="padding: 10px"
      >
        <el-table
          :data="item"
          :span-method="colSpanMethod2"
          border
          style="width: 100%; margin-bottom: 20px;"
        >
          <el-table-column prop="hbxh" label="合并序号" width="100" />
          <el-table-column prop="name" label="姓名" width="180" />
          <el-table-column prop="address" label="地址" />
        </el-table>
      </el-row>
    </el-form>
  </div>
</template>

<script>

export default {
  data() {
    return {
      spanArr: [], // 用于存放每一行记录的合并数
      testForm: {
        tableList: [
          [
            {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄',
              tbIndex: 0
            }, {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1517 弄',
              tbIndex: 0
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄',
              tbIndex: 0
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 0
            }
          ],
          [
            {
              hbxh: '1',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1518 弄',
              tbIndex: 1
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1517 弄',
              tbIndex: 1
            }, {
              hbxh: '2',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄',
              tbIndex: 1
            }, {
              hbxh: '3',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }, {
              hbxh: '4',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1516 弄',
              tbIndex: 1
            }
          ]
        ] // 测试数据
      },
    }
  },
  created() {
    this.getSpanArr2(this.testForm.tableList)
  },
  methods: {
    getSpanArr2(data) {
      for (let i = 0, l = data.length; i < l; i++) {
        let orderObj = {}
        data[i].forEach((item, index) => {
          // item.index = index
          if (orderObj[item.hbxh]) {
            orderObj[item.hbxh].push(index)
          } else {
            orderObj[item.hbxh] = []
            orderObj[item.hbxh].push(index)
          }
          this.spanArr[i] = {
            orderIndexArr: []
          }
          // 将数组长度大于1的值 存储到this.orderIndexArr(也就是需要合并的项)
          Object.keys(orderObj).forEach((key) => {
            if (orderObj[key].length > 1) {
              this.spanArr[i].orderIndexArr.push(orderObj[key])
            }
          })
        })
      }
      console.log('==========this.spanArr==========')
      console.log(this.spanArr)
    },
    colSpanMethod2({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 2) {
        for (let i = 0, l = this.spanArr[row.tbIndex].orderIndexArr.length; i < l; i++) {
          let element = this.spanArr[row.tbIndex].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 {
                return {
                  rowspan: 0,
                  colspan: 0
                }
              }
            }
          }
        }
      }
    }
  }

}
</script>

效果:
同上

来看看前端打印的信息:

到此这篇关于el-table 行合并的实现示例的文章就介绍到这了,更多相关el-table 行合并内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue使用el-table动态合并列及行

    本文实例为大家分享了vue使用el-table动态合并列及行的具体代码,供大家参考,具体内容如下 前两天项目中需要用到表单合并,特此记录,放便以后使用. 首先我使用的element-ui中的el-table,文档中提供span-method方法可以实现合并行或列,大家不熟悉的可以去看看element文档地址,但是文档提供的例子很简单,不能满足复杂的页面,所以需要处理一下数据. 如下代码: getListDataForRowAndColumn(data){ let self = this; sel

  • el-table 行合并的实现示例

    目录 示例一:单个表格 示例二:循环表格 页面实现行合并的情况还是比较常见的,但实现起来却有一点点难.官网的例子有,不过人家的合并逻辑是从第一行开始两行两行合并,不能根据数据动态合并,感觉参考意义不太大.实际需求一般都是根据表数据动态来进行合并的,也会有更复杂的情况,比如循环表格的. 以下的例子中,表格数据是放在页面的假数据,hbxh 值相同时,表示需要合并 示例一:单个表格 单个表格的比较简单,知道合并方法的使用基本就好弄了 <template> <div> <el-for

  • Element Table行的动态合并及数据编辑示例

    目录 正文 思路 1:第二列和第三列第四列根据名称进行合并 2:可以动态编辑第三列和第四列解决 3:第一列的数据是根据第三列相加得来的 4:弹出个输入框 完整代码 正文 先描述一下需求,看下图 1:动态合并行,如图所示,第一列全部合并,第二列和第三列第四列根据名称进行合并 2:可以动态编辑第三列和第四列,并且只能编辑属于此合并行的第三列和第四列,比如第一个编辑按钮点击后,只有前三行可以编辑 3:第一列的数据是根据第三列相加得来的 4:点击快捷填写,可以快速填写第三列和第四列 思路 1:第二列和第

  • JS实现动态修改table及合并单元格的方法示例

    本文实例讲述了JS实现动态修改table及合并单元格的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-

  • element-ui table span-method(行合并)的实现代码

    element-ui官网中关于行合并的例子是根据行号进行合并的,这显然不符合我们日常开发需求,因为通常我们table中的数据都是动态生成的,所以需要做一些修改.我们首先解读一下官网实例中的各参数的意义: objectSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { //用于设置要合并的列 if (rowIndex % 2 === 0) { //用于设置合并开始的行号 return { row

  • vue elementUI table 自定义表头和行合并的实例代码

    最近项目中做表格比较多,对element表格的使用,只需要传递进去数据,然后写死表头即可渲染. 但现实中应用中,如果写死表头,并且每个组件中写自己的表格,不仅浪费时间而且消耗性能.这个时候需要动态渲染表头. 而官方例子都是写死表头,那么为了满足项目需求,只能自己来研究一下. 1.自定义表头 代码如下,其实就是分了两部分,表格主数据是在TableData对象中,表头的数据保存在headerDatas,headerDatas.label其实就是表头的值,如果表头是"序号",那么header

  • python不到50行代码完成了多张excel合并的实现示例

    一 前言 公司同事最近在做excel相关的工作:今天来求助知识追寻者合并多个excel为一个一个工作本,原本是java操作poi太蛋疼了,笨重不堪,内存消耗严重,知识追寻者使用python不到40行代码完成了60多张excel工作本合并为一张:python真香 牛皮吹完了,如果看过知识追寻者系列文章的读者肯定知道之前知识追寻者发过一篇 python专题使用openpyxl操作excel:本篇使用的不是openpyx库,使用的使是xlrd,xlwt库,虽然这两库功能没法根openpyx相比,但可以

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

    目录 element-ui实现行合并过程 存在问题 关键词##: cell-mouse-enter cell-mouse-leave cell-class-name element-ui合并单元格行处理方法 获取合并规则 elemen-ui  span-method 合并方式 合并效果 element-ui实现行合并过程 目标样式: 首先先来看下我们拿到的返回数据: tableData: [ { productType: "纺织品", price: 123, productName:

  • Sql Server:多行合并成一行,并做分组统计的两个方法

    复制代码 代码如下: --创建 test 表 ,插入数据 CREATE TABLE test(code varchar(50), [values] varchar(10),[count] int)INSERT test SELECT '001', 'aa',1UNION ALL SELECT '001', 'bb',2UNION ALL SELECT '002', 'aaa',4UNION ALL SELECT '002', 'bbb',5UNION ALL SELECT '002', 'ccc

  • Pandas实现批量拆分与合并Excel的示例代码

    目录 前言 一.拆分成小表格 二.合并excel 1.介绍 2.代码 前言 提示:这里可以添加本文要记录的大概内容: 将一个EXCEL等份拆成多个EXCEL 将多个小EXCEL合并成一个大EXCEL并标记来源 提示:以下是本篇文章正文内容,下面案例可供参考 一.拆分成小表格 代码如下(示例): import pandas as pd import os work_dir=r"G:\360Downloads\myself\zuoye\合并拆分" splits_dir=f"{wo

  • vue开发table数据合并实现详解

    目录 前言 思路梳理 方案一 Element 官方 Table 组件数据合并 注意 方案二 Table-column Scoped Slot 注意 前言 项目中的某个模块,一个勾选表格数据,里面的行数据由于有关联关系,需要多行数据合并,然后勾选时选中一条数据,方便进行下一步业务操作,然后产品经理就指着原型上的表格,说:这里,这里, 数据需要合并...... 功能需求有了,里面有个技术实现点 —— 表格数据合并,下面我们就来分析一下这个表格数据合并的实现 思路梳理 方案一 Element 官方 T

随机推荐