1. 程式人生 > 程式設計 >Element實現動態表格的示例程式碼

Element實現動態表格的示例程式碼

目錄
  • 【程式碼背景】
  • 【程式碼實現】
    • #1# -> 程式碼複用的基礎是你需要一個可複用的元件
    • #2# -> 在展示頁面使用動態表格元件
    • #3# -> 如何給動態表格根據需求動態新增序號列/索引列

【程式碼背景】

有這樣一個業務需求場景,有大概十幾張表歸屬於某個類別,使用者希望在同一個頁面,通過選擇不同的查詢指標展示不同的表格,這些表的表頭樣式類似但是又不完全相同,怎麼做呢?

到目前為止所有基於Element UI的表格樣式都是直接在頁面寫死的,像官方這樣:

<el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="日期" width="180"></el-table-column>
    <el-table-column prop="name" label="姓名" width="180"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
</el-table>

要解決上述問題,最簡單暴力的方式是為每個表寫一個單獨元件,然後通過select框觸發事件切換不同元件路由渲染頁面,當然這種方式很笨,也不符合程式碼複用的基本原則,所以為了偷懶,為了堅守程式碼複用的基本原則,開始思考有沒有更好的方式來解決這個問題。

仔細觀察這個<el-table>,表格資料是通過:data繫結的,表格頭部資料則是通過<el-table-column>標籤展示的,表頭資料是不是也可以通過某種傳參的方式結合v-for來渲染<el-table-column>的具體資料呢?在度孃的幫助下,果然有大佬已經這樣做了,實現了動態表格,參考連結掛在最底下了哦,在此特別感謝免費分享知識的大佬們,知識無價,學無止境。

現將本專案的具體實現程式碼記錄如下,完善了一些程式碼的www.cppcns.com註解,嘗試幫助理解。

【程式碼實現】

#1# -> 程式碼複用的基礎是你需要一個可複用的元件

在/components/Table資料夾下新建兩個元件

DynamicTable.

<template>
  <!-- 動態展示表格 -->
  <el-table :data="tableData" border stripe :height="height" @row-click="handleRowClick">
    <!-- v-for 迴圈取表頭資料 -->
    <template v-for="item in tableHeader">
      <table-column v-if="item.children && item.children.length" :key="item.id" :column-header="item" />
      <el-table-column v-else :key="item.id" :label="item.label" :prop="item.prop" align="center" />
    </template>
  </el-table>
</template>
<script>
  import TableColumn from '@/components/Table/Tablwww.cppcns.comeColumn'
 
  export default {
    name: 'DynamicTable',components: {
      TableColumn
    },props: {
      // 表格的資料
      tableData: {
        type: Array,required: true
      },// 多級表頭的資料
      tableHeader: {
        type: Array,// 表格的高度
      height: {
        type: String,default: '300'
      }
    },methods: {
      // 行點選事件
      handleRowClick (row,column,event) {
        // console.log(row)
        // console.log(column)
        // console.log(event)
        // 通知呼叫父元件的row-click事件
        // row作為引數傳遞過去
        this.$emit('row-click',row)
      }
    }
  }
</script>

TableColumn.vue

<template>
  <el-table-column
    :label="columnHeader.label"
    :prop="columnHeader.label"
    align="center"
  >
    <!--columnHeader對應:column-header-->
    <template v-for="item in columnHeader.children">
      <tableColumn
        v-if="item.children && item.children.length"
        :key="item.id"
        :column-header="item"
      />
      <el-table-column
        v-else
        :key="item.name"
        :label="item.label"
        :prop="item.prop"
        align="center"
      />
    </template>
  </el-table-column>
</template>
 
<script>
  export default {
    name: 'TableColumn',props: {
      columnHeader: {
        type: Object,required: true
      }
    }
  }
</script>
 
<style scoped>
 
</style>

幾點重要說明:

(1)表格頭部的傳參主要分為兩類:帶children節點和不帶children節點的,如下圖所示

Element實現動態表格的示例程式碼

請注意children節點是為了完成複雜表頭的渲染,例如上面這個示例最終的表頭渲染樣式如下:

Element實現動態表格的示例程式碼

那麼問題來了,<el-table-column>是<el-table>的標籤,那這個<table-column>是個啥?

(2)DynamicTable.vue呼叫TableColumn.vue元件

Element實現動態表格的示例程式碼

DynamicTable.vue通過:column-header給TableColumn.vue傳遞帶children子節點的表頭資訊,TableColumn.vue接收到這個節點資訊後,主要做了以下兩件事情:

第一:通過<el-table-column>渲染了一個label標籤

第二:繼續判斷該節點是否存在children子節點

=> 如果存在children節點,繼續通過<table-column>進行渲染,繼續把這個子節點傳給TableColumn.vue元件,重複上述步驟

=> 如果不存在children節點,表示這是一個終止節點,通過<el-table-column>渲染結束

#2# -> 在展示頁面使用動態表格元件

<template>
  <div class="demo">
    <el-card>
      <!--查詢區域-->
      <el-row :gutter="10">
        <el-col :span="6">
          <div class="grid-content bg-purple">
            <span style="margin-right: 10px">選擇框 -</span>
            <el-select
              v-model="specified_table"
              placeholder="請選擇"
            >
              <el-option
                v-for="item in options"
                :key="item.zb_code"
                :label="item.zb_name"
                :value="item.zb_code"
              />
            </el-select>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="grid-content bg-purple">
            <el-button type="primary" plain @click="handleQueryClick">查 詢</el-button>
          </div>
        </el-col>
      </el-row>
      <!--表格區域-->
      <dynamic-table
        v-if="dynamicTableShow"
        :table-data="tableData"
        :table-header="tableHeaders"
        :height="'550px'"
      />
    </el-card>
  </div>
</template>
<script>
  // 引入元件
  import DynamicTable from '@/components/Table/DynamicTable'
  // 獲取表頭資訊
  import { getTableHeader02_1,getTableHeader02_2,getTableHeader02_3,getTableHeader02_4 } from '@/api/table-header'
 
  export default {
    name: 'Index',components: { // 元件註冊
  www.cppcns.com    DynamicTable
    },data () {
      return {
        // -- 查詢 ----------------------
        options: [
          // { zb_name: '指標名',zb_code: '指標程式碼' }
        ],specified_table: '',// 指標值
        // -- 表格 ----------------------
        dynamicTableShow: true,// DynamicTable元件重新渲染變數
        // 表頭資料
        tableHeaders: [],// 表格資料
        tableData: []
      }
    },created () {
      // api-獲取指標的下拉框資料
      getSpecifiedTable().then(res => {
        this.options = res.data
      })
    },methods: {
      // 判斷值是否在陣列中
      isExistArr (arr,val) {
        return arr.includes(val)
      },// 重新渲染表格
      refreshTable (zb_code) {
        // 根據value值獲取label值
        const obj = this.options.find((item) => {
          return item.zb_code === zb_code
        })
        console.log(zb_code)
        console.log(obj.zb_name)
        // 設定dynamicTableShow為false,使得DynamicTable元件重新渲染
        this.dynamicTableShow = false
        // 根據不同指標渲染不同的表頭
        const TBArr01 = ['M01','M02','M03','M05'] // 第1類表
        const TBArr02 = ['M04','M07','M08','M12'] // 第2類表
        const TBArr03 = ['M09','M10','M11'] // 第3類表
        const TBArr04 = ['M06'] // 第4類表
        if (this.isExistArr(TBArr01,zb_code)) {
          this.tableHeaders = getTableHeader02_1(obj.zb_name) // 渲染表頭樣式1
        }
        if (this.isExistArr(TBArr02,zb_code)) {
          this.tableHeaders = getTableHeader02_2(obj.zb_name) // 渲染表頭樣式2
        }
        if (this.isExistArr(TBArr03,zb_code)) {
          this.tableHeaders = getTableHeader02_3(obj.zb_name) // 渲染表頭樣式3
        }
        if (this.isExistArr(TBArr04,zb_code)) {
          this.tableHeaders = getTableHeader02_4(obj.zb_name) // 渲染表頭樣式4
        }
        // api - 獲取表格資料
        getTableList02(zb_code).then(res => {
          this.tableData = res.data
        })
        // 此處是DOM還沒有更新,此處的http://www.cppcns.com程式碼是必須的
        this.$nextTick(() => {
          // DOM現在更新了
          this.dynamicTableShow = true
        })
      },// 點選[查詢]事件
      handleQueryClick () {
        const zb_code = this.specified_table
        // 校驗查詢條件不能為空
        if (zb_code === '' || zb_code === undefined) {
          this.$message.warning('指標不能為空!')
        } else {
          console.log('zb_code: ' + zb_code)
          // 重新渲染表頭和表格
          this.refreshTable(zb_code)
        }
      }
    }
  }
</script>

使用動態表格元件相對來說比較簡單,唯一需要注意的地方是,渲染表格頭部跟資料時必須需要新增以下程式碼,不然頁面無法按照預期完成渲染。

this.$nextTick(() => {
    // DOM現在更新了
    this.dynamicTableShow = true
})

關於this.$nextTick()可以參考官網:https://cn.vue.org/v2/guide/reactivity.html

Element實現動態表格的示例程式碼

#3# -> 如何給動態表格根據需求動態新增序號列/索引列

在Element UI官方例子中,如果需要給table新增一個序號列或者索引列非常簡單,直接在<el-table>裡宣告一個特殊的<el-table-column>即可。

<el-table-column type="index" width="50"></el-table-column>

那如何在動態表格元件裡新增序號列呢?更甚者如果根據需要自行新增或者不新增?

首先我們來改造 DynamicTable.vue

像官方例子一樣,我們先在<el-table>裡也宣告一個<el-table-column>

<el-table-column v-if="isIndex" type="index" width="100" label="序號" align="center" />

注意到這裡有一個v-if綁定了一個isIndex值,這個值就是我們需要在父元件進行傳值的關鍵了

在props裡宣告isIndex為Boolean型別

 props: {
      // 表格的資料
      tableData: {
        type: Array,default: '300'
      },// 是否需要新增序號列
      isIndex: {
        type: Boolean
      }
}

在展示頁面使用元件時通過:is-index傳入指定引數

 <dynamic-table
        v-if="dynamicTableShow"
        :table-data="tableData"
        :table-header="tableHeaders"
        :height="'550px'"
        :is-index="true"
/>

在同頁面表頭需要切換的情況下,上面這種寫法容易在頁面初始化時候單獨顯示一個序號列,就像下面這樣,非常不美觀

Element實現動態表格的示例程式碼

我希望序號列可以和其他普通列一樣在表頭渲染的時候同時載入,可以這樣做

<dynamic-table
        v-if="dynamicTableShow"
        :table-data="tableData"
        :table-header="tableHeaders"
        :height="'550px'"
        :is-index="isAddIndex"
/>

將原本的常量“true”修改成一個變數isAddIndex替代,然後在表頭渲染完成的時候將其值修改成true

 this.isAddIndex = true

這樣序號列就能跟其他普通列同時進行渲染了。

【參考資料】

https://www.jianshu.com/p/9c4ba833658f

https://www.cnblogs.com/llcdxh/p/9473458.html

到此這篇關於Element實現動態表格的示例程式碼的文章就介紹到這了,更多相關Element 動態表格內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!