日常开发分享

961 阅读1分钟

ElementUi Table表格与分页组件的封装合并

封装的目的

  • 提高开发效率
  • 减少代码重复性
  • 提升可维护性
  • 更方便的使用

封装前后对比

封装前

 <template>
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </template>
  
   <el-pagination
    layout="prev, pager, next"
    :total="50">
  </el-pagination>
  
  data(){
      return{
          pageOPtions:{},
          table:{}
      }
  }
  

封装后

<template>
  <div>
    <PjTable
      :columns="columns"
      :list="list"
      :pagination="pagination"
    />
  </div>
</template>

<script>
import table from "./mixins/table";
import { get } from "@/api/table.js"
export default {
  name: 'home',
  mixins:[ table ],
  created() {
    this.init()
  },
  methods:{
    init(){
      this.getData()
    },
    async getData(){
      let result = await get()
      this.list = result.data
      this.pagination.total = result.meta.pageoptions.total
      console.log(result)
    }
  }
}
</script>

如何进行的封装

封装主要使用的概念是配置生成,利用vuemixin的功能,将组件分离出来成两个部分,以达到由配置生成页面的目的,下面是主要封装的组件简略代码。

<!--
@name: PjTable
@author: PJ
@description: 对element table进行二次封装
-->
<template>
  <div class="table">
    <el-table
       :data="list"
       :stripe="options.stripe"
       :border="options.border"
       :showSummary="options.showSummary"
       @selection-change="handleSelectionChange"
    >
      <!--是否开启选择框-->
         ···
      <!--设置表头-->
      <template v-for="(column,index) in columns">
        <el-table-column
           :key="column.prop"
           :prop="column.prop"
           :label="column.label"
           :fixed="column.fixed"
           :width="column.width"
           :sortable="column.sortable"
           :sort-method="column.sortMethod"
           :filters="column.filters"
           :align="column.align || 'center'"
           :filter-method="column.filters?handleFilter:undefined"
        >
          <!--支持嵌入其他组件-->
          <template slot-scope="scope">
            <template v-if="!column.render">
              <template v-if="column.formatter">
                <span v-html="column.formatter({row:scope.row, column:column,vm:$parent})"/>
              </template>
              <template v-else>
                <span>{{ scope.row[column.prop] }}</span>
              </template>
            </template>
            <template v-else>
              <renderDom :column="column" :row="scope.row" :vm="$parent" :render="column.render"
                         :index="index"/>
            </template>
          </template>
        </el-table-column>
      </template>

      <!--渲染操作按钮组-->
       ....
    </el-table>

    <!--分页-->
    <div class="page" v-if="!$globalUtils.isNull(pagination) && list.length > 0">
      <el-pagination
         :layout="pagination.layout || 'total, sizes, prev, pager, next, jumper'"
         @size-change="watchPageSize"
         @current-change="watchPageIndex"
         :background="pagination.background"
         :current-page="pagination.currentPage"
         :total="pagination.total"
         :page-sizes="pagination.pageSizes"
         :pagerCount="pagination.pagerCount"
         :page-size="pagination.pageSize"
      />
    </div>
  </div>
</template>

<script>
// createElement
export default {
  name: "PjTable",
  components: {
    renderDom: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        vm: Object,
        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, vm: ctx.parent })
      }
    }
  },
}
</script>

完整使用示例

// 组件部分
<template>
  <div>
    <PjTable
      :columns="columns"
      :list="list"
      :pagination="pagination"
    />
  </div>
</template>

<script>
import table from "./mixins/table";
import { get } from "@/api/table.js"
export default {
  name: 'home',
  mixins:[ table ],
  created() {
    this.init()
  },
  methods:{
    init(){
      this.getData()
    },
    async getData(){
      let result = await get()
      this.list = result.data
      this.pagination.total = result.meta.pageoptions.total
      console.log(result)
    }
  }
}
</script>
// mixin
const columns = [
    { prop:"name",label:"姓名" },
    { prop:"sex",label:"性别" },
    { prop:"age",label:"年龄" },
    { prop:"mobile",label:"手机号" },
]

const pagination = {
    pageSize: 10,
    currentPage: 1,
    total: 0,
}

const mixin = {
    data(){
        return{
            columns,
            list:[],
            pagination
        }
    }
}

export default mixin