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阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容