前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >element 嵌套数据合并单元格两种处理方法

element 嵌套数据合并单元格两种处理方法

作者头像
tianyawhl
发布2020-06-28 11:43:21
4.2K2
发布2020-06-28 11:43:21
举报

Element 官网有合并单元格的例子

通过table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面是{row, column, rowIndex, columnIndex} 四个属性,该函数返回包含两个元素的数组,第一个代表rowspan,第二个代表colspan。也可以返回一个键名为rowspan 和 colspan的对象

    <el-table
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%">
      <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"
        sortable
        label="数值 1">
      </el-table-column>
      <el-table-column
        prop="amount2"
        sortable
        label="数值 2">
      </el-table-column>
      <el-table-column
        prop="amount3"
        sortable
        label="数值 3">
      </el-table-column>
    </el-table>
<script>
  export default {
    data() {
      return {
        tableData: [{
          id: '12987122',
          name: '王小虎',
          amount1: '234',
          amount2: '3.2',
          amount3: 10
        }, {
          id: '12987123',
          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: '12987126',
          name: '王小虎',
          amount1: '539',
          amount2: '4.1',
          amount3: 15
        }]
      };
    },
    methods: {
      arraySpanMethod({ row, column, rowIndex, columnIndex }) {
        if (rowIndex % 2 === 0) {
          if (columnIndex === 0) {
            return [1, 2];
          } else if (columnIndex === 1) {
            return [0, 0];
          }
        }
      },

      objectSpanMethod({ row, column, rowIndex, columnIndex }) {
        if (columnIndex === 0) {
          if (rowIndex % 2 === 0) {
            return {
              rowspan: 2,
              colspan: 1
            };
          } else {
            return {
              rowspan: 0,
              colspan: 0
            };
          }
        }
      }
    }
  };
</script>

注意:上面的数据格式和普通的表格数据格式没有区别,都是一条条的数据

往往后端传给前端的数据是下面的格式,含有嵌套的数组

      tableData: [
        {
          id: 1,
          name: "name-1",
          data: [{ amount: 100 }, { amount: 200 }, { amount: 300 }]
        },
        { id: 2, name: "name-2", data: [{ amount: 1002 }, { amount: 2002 }] },
        {
          id: 3,
          name: "name-3",
          data: [
            { amount: 1003 },
            { amount: 2003 },
            { amount: 3003 },
            { amount: 3004 }
          ]
        }
      ]

这种格式的数据该怎么合并单元格呢?

第一种方法

1、首先进行数据格式转换,转换成符合官网的数据格式

2、生成合并信息的数组(那些列或者行要合并,哪些列或者行要隐藏)

3、使用span-method方法

效果图

完整代码

<template>
  <div>
    <el-table :data="tableData" :span-method="objectSpanMethod" border>
      <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="amount" sortable label="数值"></el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      rowspan: "",
      tableData: [
        {
          id: 1,
          name: "name-1",
          data: [{ amount: 100 }, { amount: 200 }, { amount: 300 }]
        },
        { id: 2, name: "name-2", data: [{ amount: 1002 }, { amount: 2002 }] },
        {
          id: 3,
          name: "name-3",
          data: [
            { amount: 1003 },
            { amount: 2003 },
            { amount: 3003 },
            { amount: 3004 }
          ]
        }
      ]
    };
  },
  methods: {
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if ([0, 1].includes(columnIndex)) {
        const _row = this.rowspan[rowIndex];
        const _col = _row > 0 ? 1 : 0;  // 如果这一行隐藏了,这列也隐藏
        return {
          rowspan: _row,
          colspan: _col
        };
      }
    },
    convertTableData() {
      let data = this.tableData;
      let arr = [];
      let rowspan = [];
      data.forEach(item => {
        //debugger
        for (let i = 0; i < item.data.length; i++) {
          let rdata = {
            ...item,
            ...item.data[i]
          };
          rdata.combineNum = item.data.length;
          delete rdata.data;
          // rdata={ id: 1,name: "name-1",amount: 1003}
          arr.push(rdata);
          // 生成合并信息的数组 [3, 0, 0, 2, 0, 4, 0, 0, 0] 其中的0代表隐藏
          if (i == 0) {
            rowspan.push(item.data.length);
          } else {
            rowspan.push(0);
          }
        }
      });
      //console.log(arr)
      this.tableData = arr;
      console.log(this.tableData);
      console.log(rowspan);
      this.rowspan = rowspan;
    }
  },

  created() {
    this.convertTableData();
  }
};
</script>

第二种方法

上面的方法感觉还是比较麻烦的,有没有更简单的方法,方法是有的,其实我们只要按照数组正常循环就可以了,如果有嵌套数组就一个单元格中放几个div,底部加一条线,外观看起来跟合并单元格效果一样

需要解决的问题是一个单元格中有几条数据,怎么使DIV占满整个单元格,设置单元格的padding为0,

    <el-table
      :data="tableData"
      style="width:100%;"
      class="margin_b20 margin_t15"
      :default-sort="{prop: 'addReducePercent', order: 'descending'}"
      :cell-style="cellStylePadding0"
      id="bigTable"
    >
      <el-table-column label="客户名称" prop="customeName" min-width="150px"></el-table-column>
      <el-table-column label="客户地址" prop="customAddress" min-width="200px;"></el-table-column>
    
        <el-table-column
          prop="addReduceQty"
          min-width="110"
          label="增减量"
          header-align="center"
          align="right"
        >
        <template slot-scope="scope">
          <div v-if="scope.row.addReduceQty>200" style="color:green">{{scope.row.addReduceQty}}</div>
          <div v-else style="color:red">{{scope.row.addReduceQty}}</div>
        </template>
        </el-table-column>
        <el-table-column
          prop="addReducePercent"
          min-width="130"
          label="增减百分比"
          header-align="center"
          align="right"
          sortable
          :sort-method="handleSort"
        ></el-table-column>
      </el-table-column>
      <el-table-column label="分路计量" header-align="center">
        <el-table-column label="名称" prop="branchName">
          <template slot-scope="scope">
            <div class="branchWrap">
              <div
                v-for="(item,index) in scope.row.branchInfo"
                :key="index"
                class="lineHeight28"
              >{{item.name}}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column
          :label="lastTime"
          header-align="center"
          align="right"
          min-width="120px"
          prop="branchLastTime"
        >
          <template slot-scope="scope">
            <div class="branchWrap">
              <div
                v-for="(item,index) in scope.row.branchInfo"
                :key="index"
                class="lineHeight28"
              >{{item.lastTimeQty}}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column
          :label="thisTime"
          header-align="center"
          align="right"
          min-width="120px"
          prop="branchThisTime"
        >
          <template slot-scope="scope">
            <div class="branchWrap">
              <div
                v-for="(item,index) in scope.row.branchInfo"
                :key="index"
                class="lineHeight28"
              >{{item.thisTimeQty}}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="增减量" header-align="center" align="right" prop="branchAddReduceQty">
          <template slot-scope="scope">
            <div class="branchWrap">
              <div
                v-for="(item,index) in scope.row.branchInfo"
                :key="index"
                class="lineHeight28"
              ><span style="color:green;" v-if="item.addReduceQty>100">{{item.addReduceQty}}</span>
              <span style="color:red;" v-else>{{item.addReduceQty}}</span>
              </div>
            </div>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>

设置padding为0 的方法

    cellStylePadding0({ row, column, ronIndex, columnIndex }) {
      if (
        column.property == "branchName" ||
        column.property == "branchLastTime" ||
        column.property == "branchThisTime" ||
        column.property == "branchAddReduceQty" ||
        column.property == "branchAddReducePercent"
      ) {
        return "padding:0";
      } else {
        return "";
      }
      //console.log(column.property)
    },

上面的例子出现百分比的比较

    handleSort(obja, objb) {
      let a = this.toPoint(obja.addReducePercent);
      let b = this.toPoint(objb.addReducePercent);
      console.log(a, b);
      if (a > b) {
        return 1;
      } else {
        return -1;
      }
    },
    /*百分数转小数*/
    toPoint(percent) {
      var str = percent.replace("%", "");
      str = str / 100;
      return str;
    },

样式

<style scoped>
.textRadio >>> .el-radio__label {
  display: none;
}
.branchWrap {
  margin: 0 -10px;
}
.branchWrap div {
  padding: 0 10px;
  border-bottom: 1px solid #dfe6ec;
}
.branchWrap div:last-child {
  border: none;
}
.lineHeight28 {
  line-height: 28px;
}
</style>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一种方法
  • 第二种方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档