专栏首页前端之攻略element 嵌套数据合并单元格两种处理方法

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

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>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何设置Element表格显示或者隐藏列

    tianyawhl
  • Element 表格导出为Excel表格

    在页面点击导出按钮时可以正常导出,但是如果左边有固定的列,相同的数据会导出2遍,可以做如下修改:

    tianyawhl
  • Element Table 动态生成列并且不同的列显示不同的样式

    我们在使用表格控件时,经常需要动态生成表格的列,并且某些列要求特殊的样式(如右对齐)

    tianyawhl
  • SQL---常用sql整理

    原文链接:http://www.w3school.com.cn/sql/sql_quickref.asp

    IT云清
  • 第二周实战作业:爬取一万商品数据

    由于没有开time.sleep所以会被反扒, 卡死之后一般用ctrl+c停止那个类目爬取……

    radaren
  • 多栏布局与JS实现瀑布流

    css3属性之多栏布局与JS实现瀑布流    背景:之前打算自己总结一下flex布局的知识点,发现自己无从下手,原因在何处:我反思了一下,其实原因很简单,使用的...

    okaychen
  • php实现登录页面的简单实例

    开始自然是从最简单的功能起步,我第一个任务选择了做一个登录操作,其实也没想象中那么简单。

    砸漏
  • 浮动之后的那些事儿 - 清浮动操作

    本文内容概要: 1 上周作业讲解 2 浮动之后的特性 3 如何清浮动 4 实例操作 上周我们讲解了如何去实现页面的简单布局,用了三种基本的CSS选择器来控制标签...

    HTML5学堂
  • 清除浮动的方法

    本章主要介绍三种常用的清除浮动的方法,主要包括: ---- [1] 增加一个空 div, 使用 clear:both 将浮动元素 "挤到" 父元素中 [2] ...

    echobingo
  • 浮动元素margin-bottom失效 — IE6盒模型

    HTML5学堂:虽然IE6慢慢的退出市场了,但是还是有必要了解一些兼容问题,让自己的知识有一个更好的沉淀。margin-bottom的bug是容器div的 'z...

    HTML5学堂

扫码关注云+社区

领取腾讯云代金券