封装一个tablelist

<!--
fetchApi:      【必填】请求api
queryList:      搜索条件
rowKey:        【建议】row的唯一性字段名称,默认为 JSON.stringify(row)
selection       是否加选择项
reserveSelection 分页查询保留之前选中的数据
childrenField   【若为树形必填】树形数据的key值,默认'children'
hasPagination   是否有分页,默认 true
defaultExpandAll 默认是否展开折叠, 默认false

@changeSelect  选择触发方法

tableColumns:
prop          【必填】后端字段名,支持多层结构,如:'userInfo.username'
label         【必填】表头(国际化)
customRender  是否做自定义渲染
filter        自动格式化,方法存放在filters/index.js的formatMap中
align         文字对齐方式,默认 center
fixed         是否固定该列,默认不固定,可选值true/left, right
width         宽度
min-width     最小宽度
 -->
<template>
  <div class="table-box">
    <el-table
      ref="commonListTable"
      v-loading="tableLoading"
      :data="fetchData"
      size="small"
      class="main-table"
      row-key="uniqueKey"
      :default-expand-all="defaultExpandAll"
      :tree-props="{'children': childrenField}"
      stripe
      @selection-change="handleSelectionChange"
      @sort-change="sortChange"
    >
      <el-table-column v-if="selection" :reserve-selection="reserveSelection" align="center" type="selection" width="50"></el-table-column>
      <template v-for="(item, index) in tableColumns">
        <el-table-column
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :align="item.align || 'left'"
          :label-class-name="item.labelClassName || ''"
          :fixed="item.fixed || false"
          :width="item.width || 'auto'"
          :sortable="item.sortable"
          :min-width="item.minWidth || 'auto'"
          :show-overflow-tooltip="item.showOverflowTooltip || false"
        >
          <template slot-scope="scope">
            <slot v-if="item.customRender" :name="scope.column.property" :row="scope.row" :$index="scope.$index" />
            <span v-else-if="item.filter">{{ getFieldByKey(scope.row,scope.column.property) | formatData(item.filter) }}</span>
            <span v-else>{{ getFieldByKey(scope.row,scope.column.property) }}</span>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <div v-if="hasPagination" class="table-pagination">
      <el-pagination
        :background="paginationConfig.background"
        :page-sizes="paginationConfig.pageSizes"
        :layout="paginationConfig.layout"
        :page-size.sync="pagination.limit"
        :current-page.sync="pagination.page"
        :total="total"
        v-bind="$attrs"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      ></el-pagination>
    </div>
  </div>
</template>

<script>

import Vue from 'vue'
export default {
  name: 'TableList',
  filters: {
    formatData(value, filter) {
      if (filter) {
        const globalFilter = Vue.filter(filter)
        if (globalFilter) {
          return globalFilter(value)
        } else {
          return filter(value)
        }
      } else {
        return value
      }
    }
  },
  props: {
    'tableColumns': { // 列表表头
      type: Array,
      require: true,
      default: function() { return [] }
    },
    'fetchData': { // 列表数据
      type: Array,
      require: true,
      default: function() { return [] }
    },
    'dataTotal': { // 列表总数
      type: Number,
      default: 0
    },
    'hasPagination': { // 是否显示分页
      type: Boolean,
      require: false,
      default: false
    },
    'pagConfig': {
      type: Object,
      require: false,
      default: function() {
        return {
          background: true, // 是否为分页按钮添加背景色
          pageSizes: [10, 20, 30, 50], // 每页显示个数选择器的选项设置
          layout: 'total, sizes, prev, pager, next, jumper'
        }
      }
    },
    'initPagination': {
      type: Object,
      require: false,
      default: function() {
        return {
          page: 1,
          limit: 10
        }
      }
    },
    'childrenField': {
      type: String,
      require: false,
      default: 'children'
    },
    'rowKey': {
      type: [String, Function],
      require: false,
      default: ''
    },
    'selection': {
      type: Boolean,
      require: false,
      default: false
    },
    'reserveSelection': {
      type: Boolean,
      require: false,
      default: false
    },
    'defaultExpandAll': {
      type: Boolean,
      require: false,
      default: false
    },
    'tableLoading': {
      type: Boolean,
      require: false,
      default: false
    },
    'autoScroll': {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {}
  },
  computed: {
    total() {
      return this.dataTotal
    },
    paginationConfig() {
      return {
        background: this.pagConfig.background,
        pageSizes: this.pagConfig.pageSizes,
        layout: this.pagConfig.layout
      }
    },
    pagination() {
      return {
        page: this.initPagination.page, // 当前页码值
        limit: this.initPagination.limit // 每页显示条目个数
      }
    }
  },
  mounted () {},
  methods: {
    // get field value by key ({}, 'aa.bb.cc')
    getFieldByKey(row, key) {
      if (key.indexOf('.') > -1) {
        let tempObj = null
        key.split('.').map(item => {
          tempObj = tempObj !== null ? tempObj[item] : row[item]
        })
        return tempObj
      } else {
        return row[key]
      }
    },
    handleSelectionChange(val) { // select
      this.$emit('selectionCloumns', val)
    },
    // pagination: select pages option
    // 每页条数改变时会触发
    handleSizeChange(limit) {
      this.pagination.limit = limit
      this.pagination.page = 1
      this.$emit('changeTablePage', this.pagination)
      if (this.autoScroll) {
        scrollTo(0, 800)
      }
    },
    // pagination: change current page
    // 当前页码值改变时会触发
    handleCurrentChange(newPage) {
      // console.log(newPage)
      this.pagination.page = newPage
      this.$emit('changeTablePage', this.pagination)
      if (this.autoScroll) {
        scrollTo(0, 800)
      }
    },
    sortChange({ column, prop, order }) { // 排序 order: ascending descending null
      column
      this.$emit('sortChange', { prop, order })
    }
  }
}
</script>

<style lang="scss" scoped>
.table-box {
  ::v-deep .el-table .el-table__empty-block {
    min-height: 100px;
  }
  .table-pagination {
    background: #fff;
    padding: 16px;
    text-align: right;
  }
  ::v-deep .el-pagination .btn-prev,
  ::v-deep .el-pagination .btn-next,
  ::v-deep .el-pagination .el-pager .number {
    height: 28px !important;
    line-height: 28px !important;
  }
  ::v-deep .el-pagination__sizes .el-select .el-input__suffix {
    height: auto;
  }
  .el-table {
    ::v-deep thead th.is-center,
    ::v-deep tbody td.is-center {
      text-align: center !important;
    }
    ::v-deep thead th.is-left,
    ::v-deep tbody td.is-left {
      text-align: left !important;
    }
    ::v-deep thead th.is-right,
    ::v-deep tbody td.is-right {
      text-align: right !important;
    }
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值