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>
如何进行的封装
封装主要使用的概念是配置生成,利用vue的mixin的功能,将组件分离出来成两个部分,以达到由配置生成页面的目的,下面是主要封装的组件简略代码。
<!--
@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