element ui Table二次封裝

element ui Table 二次封裝

表格的分頁

  • 在利用element ui Table編寫項目時,會存在表格展示的數據存在分頁的情況
    • 普遍的做法
     // 利用element ui 的 el-table與el-pagination
     <el-table :data="data">
       <el-table-column type="selection" widht="48"></el-table-column>
       <el-table-column v-for="(item,index) in columns" 
       :key="index"
       :lable="item.lable"
       :prop="item.prop"></el-table>
     </el-table>
     <el-pagination layout="prev, pager, next"
       :total="50"></el-pagination>
    
    每次編寫都需要寫那么多的標簽與方法等,何不再進行封裝,只需編寫一個標簽就完成Table表格與分頁的展示呢
    • 封裝后
     // 新建我們的組件文件如MyTable.vue文件
     <template>
       <div class="myTable">
          <el-table :data="tableData">
           <el-table-column v-if="hasSelection" type="selection" widht="48"></el-table-column>
           <el-table-column v-for="(item,index) in columns" 
           :key="index"
           :lable="item.lable"
           :prop="item.prop"></el-table>
         </el-table>
         <el-pagination v-if="hasPagination" layout="prev, pager, next"
           :total="50"></el-pagination>
       </div>
     </template>
     <script>
       export default {
         name:'myTable',
         props:{
           hasSelection:{
             type:Boolean,
             default:false
           },
           hasPagination:{
             type:Boolean,
             default:false
           },
           tableData:{
             type:Object,
             default:()=>{return {}}
           },
           columns:{
             type:Object,
             default:()=>{return {}}
           }
         },
         data(){
           return {}
         },
       }
     </script>
    
    • 在需要使用的頁面使用
     <template>
       <myTable 
         :hasSelection="hasSelection"
         :hasPagination="hasPagination"
         :tableData="tableData"
         :columns="columns"></myTable>
     </tempalte>
     <script>
     import myTable from '@/components/MyTable'
     export default {
       name:'***',
       components:{myTable}
       data(){
         return {
           hasSelection:true,
           hasPagination:true,
           tableData:{} // tableData根據后臺接口數據返回
         }
       }
       computed:{
         columns(){ // 表頭信息
           /**
            * 表頭信息為什么寫在computed里面
            * 由于我最近所的項目是基于i18n國際化的
            * 如果寫在data里面,不能根據i18n的語言切換實時進行切換
            **/ 
           return [
             {lable:'標題1',prop:'title1'},
             {lable:'標題2',prop:'title2'},
             {lable:'標題3',prop:'title3'},
           ]
         }
       }
     }
     </script>
    
    這樣我們就實現了簡單的table表格封裝,在需要使用的地方直接引入我們封裝好的組件傳入對應對應的參數就能實現表格的展示與分頁和選擇框的展示了。

列表中單元格的內容自定義

  • 上面我們已經實現了簡單的'element ui Table'封裝,但是還是不能實現一些復雜的表格展示,如圖1:
table_test.png
  • 封裝組件
<template>
  <div class="Ab_tbale">
    <el-table
      ref="table"
      element-loading-text="Loading"
      :data="tableData"
      border
      :fit="true"
      tooltip-effect="dark"
      style="width:100%"
      :max-height="maxHeight"
      @selection-change="handlerSelectChange"
      @select="handlerSelect"
      @select-all="handlerSelectAll"
    >
      <el-table-column
        v-if="hasSelect"
        type="selection"
        width="38"
      ><!--------></el-table-column>
      <el-table-column
        v-for="(item,index) in columns"
        :key="index"
        :width="item.width ? item.width : ''"
        :align="item.align"
        :label="item.label"
        :prop="item.param"
        :sortable="item.sortable ? 'custom' : false"
      >
        <template slot-scope="scope">
          <expand-dom v-if="item.render" :column="item" :row="scope.row" :render="item.render" :index="index">
            <!-- {{ item.render(scope.row) }} -->
          </expand-dom>
          <span v-else>{{ scope.row[item.param] }}</span>
        </template>
      </el-table-column>
      <el-table-column
        v-if="tableOption.label"

        :fixed="tableOption.fixed"
        :width="tableOption.width"
        :min-width="tableOption.minWidth"
        :label="tableOption.label"
        align="center"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <template v-for="(item,index) in tableOption.options">
            <el-button
              :key="index"
              :disabled="item.disabled?item.disabled(scope.row):false"
              :type="item.type"
              :size="item.size?item.size:''"
              :icon="item.icon"
              @click="handleButton(item.methods,scope.row,scope.row)"
            >
              {{ item.label }}
            </el-button>
          </template>
        </template>

      </el-table-column>

    </el-table>
    <el-pagination
      v-if="hasPageTotal"
      background
      :current-page="currentPage"
      :page-size="pageSize"
      :page-count="pageCount"
      layout="prev, pager, next"
      :total="totalPage"
      @current-change="handleCurrentChange"
    />
  </div>
</template>
<script>
export default {
  name: 'Table',
  components: {
    expandDom: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null
        }

      },
      render: (h, ctx) => {
        const params = {
          row: ctx.props.row,
          index: ctx.props.index
        }
        if (ctx.props.column) params.column = ctx.props.column
        return ctx.props.render(h, params)
      }
    }
  },
  props: {
    pageCount: { // 總頁數
      type: Number,
      default: 1
    },
    totalPage: { // 總條數
      type: Number,
      default: 1
    },
    currentPage: { // 當前頁
      type: Number,
      default: 1
    },
    pageSize: { // 每頁顯示條數
      type: Number,
      default: 10
    },
    maxHeight: { // 最大高度
      type: String,
      default: ''
    },
    hasPageTotal: { // 是否顯示分頁
      type: Boolean,
      default: false
    },
    hasSelect: { // 是否有選擇框
      type: Boolean,
      default: false
    },
    tableData: { // table表單Object
      type: Array,
      default: () => {
        return []
      }
    },
    columns: { // table表頭數據
      type: Array,
      default: () => {
        return []
      }
    },
    tableOption: { // 操作功能按鈕數據
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
    }
  },
  created() {
  },
  methods: {
    handlerSelectAll(val) {
      this.$emit('handlerSelectAll', val)
    },
    handlerSelect(value, obj) { // 選中項
      this.$emit('handlerSelect', value)
    },
    handlerSelectChange(value) {
      this.$emit('handlerSelectChange', value)
    },
    handleButton(methods, row, index) { // 按鈕事件
      this.$emit('handleButton', { 'methods': methods, 'row': row, 'index': index })
    },
    handleCurrentChange(val) {
      console.log(`當前頁: ${val}`)
      this.$emit('handlePageChange', val)
    }
  }
}
</script>
<style lang="scss">
.Ab_tbale{
  .el-pagination{
    text-align: right;
  }
  th{
    background-color:#f5f5f5;
    font-weight: bold;
  }
  .el-table-column--selection div.cell{
    text-overflow: initial !important;
  }
}
</style>
  • 組件使用
  <template>
     <myTable
        :table-data="tableData"
        :columns="columns"
        :table-option="tableOption"
        :max-height="'600px'"
        :has-select="true"
        :total-page="pageData.total"
        :current-page="pageIndex"
        :page-count="pageData.last"
        :page-size="pageData.limit"
        :has-page-total="true"
        @handleButton="handleButton"
        @handlePageChange="handlePageChange"
      ></myTable>
  </template>
  <script>
    import myTable from '@/components/MyTable'
    import { getOrderList } from '@/api/order'
    export default {
      name:'****',
      components:{myTable},
      data () {
        return {
          tableData: [], // 根據后臺接口獲得
          pageData: {}, // 頁碼對象
          pageIndex: 1
        }
      },
      computed: {
        columns() { // 表頭配置對象
          return [
            { label: this.$t('orderManagement.orderNum'), param: 'no', align: 'center', width: '' },
            { label: this.$t('orderManagement.orderTitle'), param: 'title', align: 'center', width: '' },
            { label: this.$t('orderManagement.totalSum'), param: 'totalFee', align: 'center', width: '', render: (h, params) => {
              return h('span', { class: { 'order_status_color_orang': true }}, params.row.dealFee)
            } },
            { label: this.$t('orderManagement.orderType'), param: 'statusLabel', align: 'center', width: '', render: (h, params) => {
              return h('span', {
                class: {
                  'order_status_color_gress': params.row.status === 1,
                  'order_status_color_red': params.row.status === 2 || params.row.status === 4,
                  'order_status_color_orang': params.row.status === 3,
                  'order_status_color_blue': params.row.status === 5
                }
              }, params.row.statusLabel)
            } }
          ]
        },
        tableOption() { // 操作按鈕配置對象
          return {
            label: this.$t('orderManagement.operation'),
            width: '',
            minWidth: this.minWidth,
            fixed: 'right',
            options: [
              { label: this.$t('default.see'), type: 'default', icon: 'el-icon-view', methods: 'preview', size: 'mini' },
              { label: this.$t('default.payment'), type: 'primary', icon: 'el-icon-shopping-cart-2', methods: 'payment', size: 'mini', disabled: item => {
                if (item.status === 3 || item.status === 4 || item.status === 5) {
                  return true
                } else {
                  return false
                }
              } },
              { label: this.$t('orderManagement.orderClose'), type: 'danger', icon: 'el-icon-error', methods: 'close', size: 'mini', disabled: item => {
                if (item.status < 3) {
                  return false
                } else {
                  return true
                }
              } }
            ]
          }
        }
      },
      mounted(){
        this.getList()
      },
      methods: {
        handlePageChange(pageIndex) {
          var data = {}
          data.page = pageIndex
          getOrderList(data).then(res => {
            if (res.code === 0) {
              this.tableData = res.data.list
              this.pageData = res.data.page
            }
          })
        },
        getList() {
          var data = {}
          data.page = this.pageIndex
          getOrderList(data).then(res => {
            if (res.code === 0) {
              this.tableData = res.data.list
              this.pageData = res.data.page
            }
          })
        },
        handleButton(data) {
          var funType = data.methods
          if (funType === 'close') {
            this.orderClose(data.row.no)
          } else {
            this.showPopDetial(data.methods, data.row.no)
            this.selectOrderItem = data.row
          }
        }
      }
    }
  </script>
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容