element 嵌套數據合併單元格兩種處理方法

Element 官網有合併單元格的例子javascript

經過table傳入span-method方法能夠實現合併行或列,方法的參數是一個對象,裏面是{row, column, rowIndex, columnIndex} 四個屬性,該函數返回包含兩個元素的數組,第一個表明rowspan,第二個表明colspan。也能夠返回一個鍵名爲rowspan 和 colspan的對象css

<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>

注意:上面的數據格式和普通的表格數據格式沒有區別,都是一條條的數據html

每每後端傳給前端的數據是下面的格式,含有嵌套的數組前端

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 }
          ]
        }
      ]

這種格式的數據該怎麼合併單元格呢?java

第一種方法

一、首先進行數據格式轉換,轉換成符合官網的數據格式後端

二、生成合並信息的數組(那些列或者行要合併,哪些列或者行要隱藏)數組

三、使用span-method方法函數

效果圖this

完整代碼spa

<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>
相關文章
相關標籤/搜索