基于ElementUI封装一套更加简单易用的表格组件
我要用表格,涉及到分页。
然后发现网上很多表格组件封装的思路都一样,公司项目里的也一样,不好用,主要是:
1.表格结构不直观,我想在html模板中就能看到我的表格项。
2.插槽写法太麻烦。
3.每次都要在父组件处理分页逻辑,很烦人,不够智能。
4.使用起来要写的代码相对还是挺多,我想让它更精简。
所以今晚回来自己封装了一套(非常好用,已经测试ok了):
先看怎么用:
先引入:import Table from '@/components/Table/index.vue'
然后放在模板里,表格项目直接丢进去:
<Table ref="table" :get-data-method="getTableData" >
<el-table-column label="表头1" prop="propName1" />
<el-table-column label="表头2" prop="propName2" />
<el-table-column label="表头3" prop="propName3" />
//插槽写法,和vue完全一致,没有额外理解成本
<el-table-column label="操作">
<template v-slot:default="{row}">
{{ row }}
</template>
</el-table-column>
</Table>
你只需要提供一个获取数据的方法给这个组件,内部会帮你处理分页。
这里用了ref引用,用于调用组件内部的方法,主要就是执行数据获取。
看下methods里:
// 获取表格数据
getTableData () {
return new Promise((resolve, reject) => {
resolve({
data: [
{id: 111},
{id: 111},
],
totalCount: 10
})
})
},
//调用组件内部获取数据的方法(其实就是上面我们传入的)
search (params) {
this.$refs.table.getTableData(params)
},
组件挂载完毕后就获取一次数据
// 组件挂载完毕后就获取一次数据
mounted () {
this.search(this.form)
},
然后分页的变化逻辑你根本就不用处理了,什么pageSize的变化,currentPage的变化,组件内部都帮你做了。是不是够爽?你只需要传入一个获取数据的方法给它。
下面是组件实现的完整代码,拿去直接能用。
<template>
<div class="Table_container">
<el-table
:data="tableData"
stripe
>
<slot></slot>
</el-table>
<div class="pagination">
<el-pagination
:page-sizes="pageSizes"
:current-page="paginationInfo.currentPage"
:page-size="paginationInfo.pageSize"
:total="totalCount"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script>
export default {
name: 'Table',
props: {
pageSize: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default () {
return [10, 15, 20, 25, 30, 35, 40, 45, 50]
}
},
getDataMethod: {
type: Function,
require: true,
default () {
return () => {}
}
}
},
data () {
return {
params: {},
paginationInfo: {
pageSize: undefined,
currentPage: 1
},
totalCount: 0,
tableData: []
}
},
created () {
// 从props初始化传入的分页数据
this.paginationInfo.pageSize = this.pageSize
},
methods: {
// 获取表格数据
async getTableData (params) {
this.params = params
const res = await this.getDataMethod({
...this.params,
...this.paginationInfo
})
this.tableData = res.data
this.totalCount = res.totalCount
},
// pageSize变化
handleSizeChange (val) {
this.paginationInfo.pageSize = val
this.paginationInfo.currentPage = 1
this.getTableData(this.params)
},
// 当前页(currentPage)变化
handleCurrentChange (val) {
this.paginationInfo.currentPage = val
this.getTableData(this.params)
}
}
}
</script>
<style lang="less" scoped>
.Table_container {
flex: 1;
height: 100%;
.pagination {
padding-top: 10px;
display: flex;
justify-content: end;
}
}
</style>
拿去吧同志们,我要睡觉了。