100行代码~table表格封装(源码)🔥

174 阅读1分钟

100行代码~table表格封装(源码)🔥

基于element组件
自定义Table组件,用于整合页码组件el-pagination;已优化colums的写法

目的

解决table和分页组件每次都要分开写的问题

  1. 分页组件合并封装
  2. 页码能方便重置

优化模版colum过多

  1. 使用数组遍历渲染
  2. 插槽参考switch

组件缩略图

thumbnail.jpg

使用

    <!-- 表格 -->
    <sp-table
      class="table"
      :data="tableData"
      :columns="columns"
      :paginationSeting="paginationSeting"
      style="width: 100%"
      height="550"
      stripe
      @done="val => (tableInstance = val)"
    >
      <!-- 手机号自定义渲染 -->
      <template slot="mobile" slot-scope="scope">
        <div>手机号:{{ scope.row.mobile }}</div>
      </template>
      <!-- 操作自定义渲染 -->
      <template slot="operation" slot-scope="scope">
        <div>{{ scope.row.id }}</div>
      </template>
      <template slot="operationHeader" slot-scope="scope">
        <div>{{ scope.column.label }}(功能区域)</div>
      </template>
    </sp-table>

Props

table的属性方法都没有改变官网保持一致

参数类型默认值可选项备注
paginationSetingObject默认--el-pagination组件属性一致,方法当做属性传递
columnsObject默认--请看下面的结构
doneFunction默认--初始化完成函数

columns的属性与官网Table-column Attributes保持一致,一下是增量属性

参数类型默认值可选项备注
scopedSlotSrting----是否使用自定义插槽来渲染
isSlotHeaderBoolean----是否自定义渲染表头cloum,表头插槽为${scopedSlot}Header

Methods(与el-table一致)

方法名参数返回值备注
--------

Slot (与el-table一致)

name说明
-

代码

<template>
  <div>
    <!-- 表格 -->
    <el-table v-bind="$attrs" v-on="$listeners" ref="refTable">
      <template v-for="(col, index) in columns">
        <el-table-column v-if="!col.scopedSlot" v-bind="col" :key="index">
        </el-table-column>
        <el-table-column v-else :key="index" v-bind="col">
          <template slot="header" slot-scope="scope">
            <slot
              v-if="col.isSlotHeader"
              :name="`${col.scopedSlot}Header`"
              v-bind="{ col: col, column: scope.column }"
            >
            </slot>
            <div v-else>{{ scope.column.label }}</div>
          </template>
          <template slot-scope="scope">
            <slot :name="col.scopedSlot" v-bind="{ col: col, row: scope.row }">
            </slot>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页组件 -->
    <el-pagination
      v-bind="paginationOptions"
      class="pagination"
      :class="paginationSeting.class"
      :style="paginationSeting.style"
      :total="paginationSeting.pageTotal"
      :current-page="paginationOptions.currentPage"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      @prev-click="paginationOptions.prevClick"
      @next-click="paginationOptions.nextClick"
    >
    </el-pagination>
  </div>
</template>
<script>
export default {
  name: 'spTable',
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    paginationSeting: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      // 分页组件默认属性设置
      paginationOptions: {
        currentPage: 1,
        pageSize: 10,
        pageTotal: 0,
        background: true,
        pageSizes: [10, 30, 50, 100],
        layout: 'total,  prev, pager, next,sizes, jumper',
        prevClick: () => {},
        nextClick: () => {}
      }
    }
  },
  created() {
    // 0. 合并分页组件参数
    this.paginationOptions = {
      ...this.paginationOptions,
      ...this.paginationSeting
    }
  },
  mounted() {
    // 0. 返回表格实例对象
    if (this.$refs.refTable) this.$emit('done', this.$refs.refTable)
  },
  methods: {
    /**
     * @description: 分页组件
     * @author: zhj1214
     */
    handleSizeChange(val) {
      this.pageSize = val
      this.paginationOptions.sizeChange(val)
    },
    handleCurrentChange(val) {
      this.currentPage = val
      this.paginationOptions.currentChange(val)
    }
  }
}
</script>
<style lang="scss" scoped>
.pagination {
  position: relative;
  margin-top: 15px;
  display: flex;
  justify-content: end;
}
::v-deep {
  .el-pagination__total {
    position: absolute !important;
    left: 0 !important;
  }
}
</style>