element-ui表格的二次封裝

在使用element-ui的時候,雖說element官方的el-table組件已經至關好了,但針對的是因此羣體,若是咱們在寫後臺系統的時候但願更多的去封裝已減小重複勞動。此次趁本身在寫後臺系統的時間來具體記錄下如何去封裝的。element-ui

分析element-ui官方的el-table組件

表格屬性

首先須要分析出那些屬性是項目中必須每次都須要的,這種屬性適合默認值,若是不是必須的但又用到了的能夠做爲可配置項。根據本身的項目其實最經常使用的屬性data、stripe,其它的屬性你們能夠根據本身的項目視具體狀況而定。數組

表格方法

方法中在目前的項目中是沒有使用到的,可是有一個應該是會有人用到的,sort-changebash

表格項的屬性

表格的每一項的屬性應該是最多的了,畢竟須要配置的也就是表格的每一項了,主要有label、prop、width、fixed、sortable、formatter、show-overflow-tooltip,其實這裏根據本身的項目還須要加一個是否爲圖片的屬性,畢竟表格裏面顯示圖片仍是顯示不下的須要使用其餘組件來顯示圖片,暫定屬性爲isImg。ui

表格操做按鈕

一般後臺系統最後一列都須要一個操做,畢竟有不少數據時須要人工進行操做的,因此須要添加一些操做的按鈕來對某一行數據進行操做。this

定義想象的數據模型

根據上面的分享接下來咱們先把須要的數據或則是配置項定義下來,這樣後面定義組件的時候就能夠根據定義的數據或則配置項來生成表格的內容。spa

表格數據的屬性

根據上面的分享表格數據的屬性就兩個data和stripe,這裏須要外加一個loading,因此結構就像下面這樣的:3d

<template>
  <div class="home">
      test
  </div>
</template>

<script>

export default {
  name: "home",
  data() {
    return {
      table: {
        stripe: false, //是否爲斑馬紋
        loading: false, // 數據加載loading
      }
    };
  },
  mounted() {}
};
</script>
複製代碼

目前沒有數據因此能夠先關閉loading和stripecode

接下來就是最重要的數據了,目前沒有接口因此這裏使用本身手動添加數據,也就是在table對象中添加data這樣一個數組來保存表格的數據,以下:component

data() {
    return {
      table: {
        stripe: false, //是否爲斑馬紋
        loading: false, // 數據加載loading
        data: [
          {
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀區江路 1518 弄"
          },
          {
            date: "2016-05-04",
            name: "王小虎",
            address: "上海市普陀區江路 1517 弄"
          },
          {
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀區江路 1519 弄"
          },
          {
            date: "2016-05-03",
            name: "王小虎",
            address: "上海市普陀區江路 1516 弄"
          }
        ]
      }
    };
  }
複製代碼

這樣表格的屬性也就差很少了。orm

表格的方法

表格的方法也就一個就是排序的,因項目中沒有用到因此這裏只是提供一個思路,具體實現的細節你們能夠本身去補充,在table對象裏面新添加一個event配置項以下:

event: {
	sortEvent: this.tableSort
}
複製代碼

這裏的tableSort就不具體寫了,你們能夠本身參考element-ui官方來寫這個排序的查詢。

表格每一項數據的屬性

這個也是重點須要配置的,先定義幾組數據模型,也就是在table對象中添加一個數組header用於表格的生成,以下:

header: [
          {
            prop: "selection",
            width: "55"
          },
          {
            prop: "date",
            label: "日期11"
          },
          {
            prop: "date",
            label: "日期11",
            width: "180",
            formatter: "",
            tooltip: false,
            sortable:false,
            fixed: "right"
          },
          {
            prop: "date",
            label: "日期11",
            width: "180",
            formatter: "",
            tooltip: false,
            sortable:false,
            isImg:false,
            fixed: "right"
          },
          {
            prop: "options",
            label: "操做",
            width: "180",
            fixed: "right"
          }
        ]
複製代碼

數組中第一個和最後一個位置最好不要動,第一個是多選操做,最後一個是操做欄

表格數據的操做按鈕

有了操做欄那麼就須要有操做的按鈕,先定義一個試試看,以下:

options: [
          {
            type: "success",
            label: "經過",
            event: this.submitBtn,
            isShow: item => {
              return item.status == 0 ? false : true;
            }
          }
        ]
複製代碼

isShow爲何時候顯示該按鈕,這裏有一個回調來配置,須要返回一個布爾值

表格組件的定義

表格的基礎數據定義好了就能夠開始定義表格組件了,新建一個table組件,而後添加以下代碼:

<template>
  <el-table :data="table.data" v-loading="table.loading" :stripe="table.stripe">
      
  </el-table>
</template>

<script>
export default {
  props: {
    table: Object
  }
};
</script>
複製代碼

這時候是看不到任何效果的,因此先在頁面中引入該組件(上面生成數據的頁面中),接下來就是生成表格的內容了。

生成多選操做

多選操做在配置的時候就是prop的值爲selection,因此直接在循環中判斷便可,以下:

<template v-for="item in table.header">
        <el-table-column type="selection" :width="item.width" v-if="item.prop == 'selection'"></el-table-column>
</template>
複製代碼

效果以下:

生成列表項

列表項就是具體的表格項屬性了,配置好基本上表格的數據也就能看到了,這裏就不單個去說了,直接看最終代碼吧:

<template>
  <el-table :data="table.data" v-loading="table.loading" :stripe="table.stripe">
    <template v-for="item in table.header">
      <el-table-column type="selection" :width="item.width" v-if="item.prop == 'selection'"></el-table-column>
      <template v-else-if="item.prop == 'options'">
        <template v-if="table.options.length">
          <el-table-column :label="item.label" :width="item.width" :fixed="item.fixed">
            <template slot-scope="scope">
              <template v-for="btn in table.options">
                <el-button
                  :type="btn.type"
                  v-if="btn.isShow ? btn.isShow(scope.row) : true"
                  @click="btn.event(scope.row)"
                >{{btn.label}}</el-button>
              </template>
            </template>
          </el-table-column>
        </template>
      </template>
      <template v-else>
        <template v-if="item.isImg">
          <el-table-column :prop="item.prop" :label="item.label" :width="item.width">
            <template slot-scope="scope">
              <el-popover placement="left" trigger="click">
                <div>
                  <el-image
                    style="width: 300px; height: auto;"
                    :src="scope.row[item.prop]"
                    fit="contain"
                    slot="reference"
                  ></el-image>
                </div>
                <el-image
                  style="width: 100px;height: 100px;"
                  :src="scope.row[item.prop]"
                  fit="contain"
                  slot="reference"
                ></el-image>
              </el-popover>
            </template>
          </el-table-column>
        </template>
        <el-table-column
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :formatter="item.formatter?item.formatter:null"
          :show-overflow-tooltip="item.tooltip?item.tooltip:false"
          :sortable="item.sortable?item.sortable:false"
          v-else
        ></el-table-column>
      </template>
    </template>
  </el-table>
</template>

<script>
export default {
  props: {
    table: Object
  }
};
</script>
複製代碼

修改初始數據

這個時候基本封裝好了,對於剛開始的初始數據作以下修改便可:

<template>
  <div class="home">
    <my-table :table="table"></my-table>
  </div>
</template>

<script>
import myTable from "@/components/Table";

export default {
  name: "home",
  components: {
    "my-table": myTable
  },
  data() {
    return {
      table: {
        stripe: false, //是否爲斑馬紋
        loading: false, // 數據加載loading
        data: [
          {
            date: "2016-05-02",
            name: "王小虎",
            img:
              "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
            address: "上海市普陀區江路 1518 弄"
          },
          {
            date: "2016-05-04",
            name: "王小虎",
            img:
              "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
            address: "上海市普陀區江路 1517 弄"
          },
          {
            date: "2016-05-01",
            name: "王小虎",
            img:
              "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
            address: "上海市普陀區江路 1519 弄"
          },
          {
            date: "2016-05-03",
            name: "王小虎",
            img:
              "https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg",
            address: "上海市普陀區江路 1516 弄"
          }
        ],
        event: {
          sortEvent: this.tableSort
        },
        header: [
          {
            prop: "selection",
            width: "55"
          },
          {
            prop: "date",
            label: "日期11",
            width: "180",
            formatter: ""
          },
          {
            prop: "name",
            label: "名稱",
            tooltip: false,
            sortable: false
          },
          {
            prop: "img",
            label: "頭像",
            width: "180",
            isImg: true
          },
          {
            prop: "address",
            label: "地址",
            width: "180",
            tooltip: true
          },
          {
            prop: "options",
            label: "操做",
            width: "200",
            fixed: "right"
          }
        ],
        options: [
          {
            type: "success",
            label: "經過",
            event: this.checkPass,
            isShow: item => {
              return item.status == 0 ? false : true;
            }
          },
          {
            type: "danger",
            label: "不經過",
            event: this.checkNoPass,
            isShow: item => {
              return item.status == 1 ? false : true;
            }
          }
        ]
      }
    };
  },
  methods: {
    tableSort(val) {
      console.log(val);
    },
    checkPass(val) {
      console.log(val);
    },
    checkNoPass(val) {
      console.log(val);
    }
  }
};
</script>
複製代碼

效果以下:

相關文章
相關標籤/搜索