Element實現表格嵌套、多個表格共用一個表頭的方法;

一、分析需求

  • 這裏先上一張圖說明 需求

根據後端返回的數據 (res 是一個數組,它的元素是一個對象,對象裏面的ext屬性是一個對象,它又包含了,defaultfreepay三個屬性,且這三個都是數組格式。):
在這裏插入圖片描述

  • 渲染出一個這樣子的 表格

res數據:

  1. res的每一個元素的直接屬性name (即爲郵費模板名稱,比如成都運費模板),
  2. resext屬性下的三個數組 defaultfreepay,每一個數組要大的一行(這一行中,第一列是運送到的地址的名字,這裏定義的是area屬性,但後端是未給到這個字段的,可自己處理數據添加該字段 ,這裏就不細說了。) 這個area屬性佔據的這一列,在頁面的展示效果 應該是多行合併的效果。在這裏插入圖片描述

二、代碼實現:

<template>
    <div class="layout">
      <el-table :data="res" >
        <el-table-column prop="name">
          <template slot-scope="scope">
            <div class="tab_header">
              <span style="font-weight:600;">{{scope.row.name}}</span>
              <div class="operate">
                <span @click="handleEdit(scope.$index, scope.row)">修改</span>
                <span @click="handleDelete(scope.$index, scope.row)">刪除</span>
              </div>
            </div>

            <!-- 這裏要實現 多個表格共用一個表頭,故需做判斷,當表格要渲染的數據爲default這個數組的時候,才顯示錶頭的label值 -->
            <!-- 注意:當label無值的時候,還是會佔用空間,故當前表格在頁面上會出現一個代表表頭的空行,需要手動更改(重寫)Element表格的 thead樣式 -->

            <div v-for="item in (scope.row.ext)" :key="item.id">
              <el-table :data="item" border :class="item!==scope.row.ext.default?'tab-thead-style':''"  style="box-sizing: border-box;border-top:none;" :span-method="objectSpanMethod">
                <el-table-column :label="item===scope.row.ext.default?'運送到':''" prop="area"></el-table-column>
                <el-table-column :label="item===scope.row.ext.default?'首重':''" prop="weight"></el-table-column>
                <el-table-column :label="item===scope.row.ext.default?'運費':''"   prop="first_price"></el-table-column>
                <el-table-column :label="item===scope.row.ext.default?'續重':''"  prop="weight_incre"></el-table-column>
                <el-table-column :label="item===scope.row.ext.default?'最終運費':''"  prop="extend_price"></el-table-column>
              </el-table>
            </div>

          </template>
        </el-table-column>
      </el-table>
    </div>
</template>
<script>
export default {
  data () {
    return {
      // res 參考的是後端返回的數據格式,
      res: [
        {
          id: 1,
          dealer_id: 0,
          name: '成都運費模板',
          type: 1,
          ext: {
            default: [{ area: '默認', type: 1, region: '1', weight: '首重d', weight_incre: '續重d', first_price: '運費d', extend_price: '最終運費d' }],
            free: [{ area: 'free', type: 1, region: '1', weight: '首重f', weight_incre: '續重f', first_price: '運費f', extend_price: '最終運費f' }, { area: 'free', type: 1, region: '1', weight: '首重f', weight_incre: '續重f', first_price: '運費f', extend_price: '最終運費f' }],
            pay: [{ area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }]
          }
        },
        {
          id: 2,
          dealer_id: 0,
          name: '重慶運費模板',
          type: 2,
          ext: {
            default: [{ area: '默認1', type: 1, region: '1', weight: '首重d', weight_incre: '續重d', first_price: '運費d', extend_price: '最終運費d' }],
            free: [{ area: 'free1', type: 1, region: '1', weight: '首重f', weight_incre: '續重f', first_price: '運費f', extend_price: '最終運費f' }, { area: 'free', type: 1, region: '1', weight: '首重f', weight_incre: '續重f', first_price: '運費f', extend_price: '最終運費f' }],
            pay: [{ area: 'pay1', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay1', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }, { area: 'pay', type: 1, region: '1', weight: '首重p', weight_incre: '續重p', first_price: '運費p', extend_price: '最終運費p' }]
          }
        }

      ]
    }
  },
  methods: {
    handleEdit (index, row) {
      console.log(index, row)
    },
    handleDelete (index, row) {
      console.log(index, row)
    },
    objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        if (rowIndex === 0) {
          let maxLen
          this.res.forEach(val => {
            const arr = [val.ext.default.length, val.ext.free.length, val.ext.pay.length]
            arr.sort((a, b) => a - b)// arr數組  按數字大小從小到大排序
            maxLen = arr.pop()// 取出排序後的數組arr中的最後一個元素
          })
          return {
            // 這個rowspan應該據 ext的default,pay,free的長度不同來定,取最大長度
            rowspan: maxLen,
            colspan: 1
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    }
  }
}
</script>
<style lang="scss">
.layout{

  .tab_header{
   color:#333;
   padding:0 5px 0 5px;
   height:45px;
   line-height:45px;
   border:1px solid #eee;display:flex;
   justify-content: space-between;
   background:rgb(233, 225, 225);
  }
  .operate{
    span{
      font-size: 14px;
      margin-right: 20px;
      margin-right:20px;
      color:#409EFF;
      cursor: pointer;
    }
  }
  /* 處理多個表格共用一個表頭時,表頭處出現多餘空行的問題 (label置空後還是佔據空間問題) */
  .tab-thead-style{
      thead{
          display: none;
      }
  }

}
</style>


在這裏插入圖片描述

三、知識點總結:

  • 爲什麼要採用這種方式解決(渲染)?

    ① . 項目用的UI組件是Element,它的Table表格組件,沒有直接處理行的操作。

    ② . el-table,它是通過注入data對象數組,並在el-table-column 中用prop屬性來對應對象中的鍵名來填入數據,從而渲染出渲染表格。其中el-table-column表示一個列,label屬性來定義表格的列名,即對象的一個鍵名代表一列;

    ③ . 沒想到更優的解決辦法,O(∩_∩)O哈哈~

  • 多個表格共用一個表頭時,注意:

    ①. 需做判斷,同時注意label的值。

    ②.el-table-column 的屬性label無值的時候,還是會佔用空間,故當前表格在頁面上會出現一個代表表頭的空行,需要手動更改(重寫)Element表格的 thead樣式

  • table表格嵌套的時候,注意:

    ① . ElementTable組件可 自定義列模板,主要是利用它實現表格嵌套部分,通過 Scoped slot 可以獲取到 row, column, $indexstore(table 內部的狀態管理)的數據,更多用法參考官網

    ②. ElementTable組件可 合併行或列 ,多行或多列共用一個數據時,可以合併行或列;通過給table傳入span-method方法可以實現合併行或列,參考上述代碼的 **objectSpanMethod**方法(該表格的第一列需要合併多行——合併渲染表格的data數組的長度那麼多行) 或者官網。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章