Element 单元格合并

前言

最近有个需求,要对相同值的单元格进行合并,踩了一下坑,顺便记录一下,方便以后的使用。

欢迎留言,允许转载,转载麻烦说明来源,创作不易

实现

官方api

:span-method="objectSpanMethod"
objectSpanMethod({
    
     row, column, rowIndex, columnIndex })

row代表行属性,column代表列属性,rowIndex代表行下标,columnIndex代表列下标

初始数据

<template>
    <div>
     <el-table :data="tableData"  border style="width: 60%">
  <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1"  label="数值1" />
      <el-table-column prop="amount2"  label="数值2" />
     </el-table>
    </div>
</template>

<script>
export default {
    
    
    data() {
    
    
        return {
    
    
          tableData:[
            {
    
    name:'Tom',amount1:10,amount2:15},
            {
    
    name:'Tom',amount1:11,amount2:16},
            {
    
    name:'Jack',amount1:12,amount2:17},
            {
    
    name:'Andy',amount1:13,amount2:18},
            {
    
    name:'Andy',amount1:14,amount2:19}
          ]
        };
    },
    methods: {
    
    
    }
};
</script>

在这里插入图片描述

实例1:合并第一列的前两行

//合并方法
 objectSpanMethod({
     
      row, column, rowIndex, columnIndex }){
    
    
     if(columnIndex==0){
    
    
         //如果是第一行,就合并两行
         if(rowIndex==0){
    
    
             return {
    
    
                 rowspan:2,
                 colspan:1
             } 
         }
     }
 }

在这里插入图片描述
可以看出是数据错列了。原因如下:

虽然第0行,让他合并了两行一列,但是第二行的那个tom是还存在的,所以导致错行。
正确的方式应该是第一行合并后,其余多出来的应该隐藏掉。隐藏单元格可以通过{rowspan:0,colspan:0}来实现,表示不渲染(两个都等于0,或者某一个等于0都行,后面会用到这里)

 //合并方法
    objectSpanMethod({
     
      row, column, rowIndex, columnIndex }) {
    
    
      let _row = 2;
      if (columnIndex == 0) {
    
    
        //如果是第一行,就合并两行
        if (rowIndex == 0) {
    
    
          return {
    
    
            rowspan: _row,
            colspan: 1,
          };
        } else {
    
    
          //其他行
          //因为合并了前两行,第0行已经占两行了,第一行,应该隐藏,其他行正常显示
          if (rowIndex < _row) {
    
    
            return {
    
    
              rowspan: 0,
              colspan: 1,
            };
          }
        }
      }
    },

在这里插入图片描述

实例2:第一列相同姓名的行合并

上面那个例子,实际用处不大,但是可以作为一个很好理解的例子。基于实例1,开始实现实例2 。

数据可以简化成 Tom Tom Jack Andy Andy,按照实例1,合并的行数应该是2,0,1,2,0(2表示合并两行,0表示要隐藏,依次类推),得到这几个数字就是我们需要处理的逻辑,具体逻辑如下:

//获取要合并的行数
getSpanNumber(data, prop) {
    
    
  //data要处理的数组,prop要合并的属性,比如name

  //数组的长度,有时候后台可能返回个null而不是[]
  let length = Array.isArray(data) ? data.length : 0;
  if (length > 0) {
    
    
    //用于标识位置
    let position = 0;
    //用于对比的数据
    let temp = data[0][prop];
    //要返回的结果
    let result = [1];
    //假设数据是AABCC,我们的目标就是返回20120
    for (let i = 1; i < length; i++) {
    
    
      if (data[i][prop] == temp) {
    
    
        //标识位置的数据加一
        result[position] += 1;
        //当前位置添0
        result[i] = 0;
      } else {
    
    
        //不相同时,修改标识位置,该位置设为1,修改对比值
        position = i;
        result[i] = 1;
        temp = data[i][prop];
      }
    }
    //返回结果
    return result;
  } else {
    
    
    return [0];
  }
},

测试一下数据:

 mounted() {
    
    
   console.log("结果:", this.getSpanNumber(this.tableData,'name'));
 },

在这里插入图片描述

实现上面的需求


<template>
  <div>
    <el-table :data="tableData" border style="width: 60%" :span-method="objectSpanMethod">
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1" label="数值1" />
      <el-table-column prop="amount2" label="数值2" />
    </el-table>
  </div>
</template>

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      tableData: [
        {
    
     name: "Tom", amount1: 10, amount2: 15 },
        {
    
     name: "Tom", amount1: 11, amount2: 16 },
        {
    
     name: "Jack", amount1: 12, amount2: 17 },
        {
    
     name: "Andy", amount1: 13, amount2: 18 },
        {
    
     name: "Andy", amount1: 14, amount2: 19 },
      ],
    };
  },
  mounted() {
    
    
    console.log("结果:", this.getSpanNumber(this.tableData, "name"));
  },
  methods: {
    
    
    //合并方法
    objectSpanMethod({
     
      row, column, rowIndex, columnIndex }) {
    
    
      if (columnIndex == 0) {
    
    
        //合并相同的名字
        let nameSpan = this.getSpanNumber(this.tableData, "name");
        return {
    
    
          rowspan: nameSpan[rowIndex],
          colspan: 1,
        };
      }
    },
    //获取要合并的行数
    getSpanNumber(data, prop) {
    
    
      //data要处理的数组,prop要合并的属性,比如name

      //数组的长度,有时候后台可能返回个null而不是[]
      let length = Array.isArray(data) ? data.length : 0;
      if (length > 0) {
    
    
        //用于标识位置
        let position = 0;
        //用于对比的数据
        let temp = data[0][prop];
        //要返回的结果
        let result = [1];
        //假设数据是AABCC,我们的目标就是返回20120
        for (let i = 1; i < length; i++) {
    
    
          if (data[i][prop] == temp) {
    
    
            //标识位置的数据加一
            result[position] += 1;
            //当前位置添0
            result[i] = 0;
          } else {
    
    
            //不相同时,修改标识位置,该位置设为1,修改对比值
            position = i;
            result[i] = 1;
            temp = data[i][prop];
          }
        }
        //返回结果
        return result;
      } else {
    
    
        return [0];
      }
    },
  },
};
</script>

结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41897680/article/details/121837200