本文章旨在对element-ui中的表格组件进行二次封装 分为三部分:
- 封装el-pagination组件
- 使用封装好的组件
- 将table,search组件结合使用
第一部分 -封装
// pagination.vue
<template>
<div class="pagination-container">
<ks-el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</ks-el-pagination>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import {
Pagination,
} from '@ks/ks-element-ui';
@Component({
name: 'pagination-common',
components: {
KsElPagination: Pagination,
},
})
export default class PaginationCommon extends Vue {
@Prop({
type: Number,
required: true,
})
total!: number;
@Prop({
type: Number,
default: 1,
})
page!: number;
@Prop({
type: Number,
default: 20,
})
limit!: number;
@Prop({
type: Array,
default() {
return [10, 20, 30, 50];
},
})
pageSizes!: object;
@Prop({
type: String,
default: 'total, sizes, prev, pager, next, jumper',
})
layout!: string;
@Prop({
type: Boolean,
default: false,
})
background!: boolean;
@Prop({
type: Boolean,
default: false,
})
autoScroll!: boolean;
@Prop({
type: Boolean,
default: false,
})
hidden!: boolean;
public get currentPage() {
return this.page;
}
public set currentPage(val: any) {
this.$emit('update:page', val);
}
public get pageSize() {
return this.limit;
}
public set pageSize(val: any) {
this.$emit('update:limit', val);
}
handleSizeChange(val: any) {
this.$emit('pagination', { page: this.currentPage, limit: val });
if (this.autoScroll) {
scrollTo(0, 800);
}
}
handleCurrentChange(val: any) {
this.$emit('pagination', { page: val, limit: this.pageSize });
if (this.autoScroll) {
scrollTo(0, 800);
}
}
}
</script>
2. 第二部分:-使用
// index.vue 使用文件
<Pagination
style="text-align: right;margin-top: 20px;"
:total="total"
:page.sync="pipelinePage"
:limit.sync="pageSize"
@pagination="pagination"
>
</Pagination>
data() {
pipelinePage = 1;
pageSize = 20;
}
methods: {
pagination(pageinfos: any) {
this.searchForm.offset = (pageinfos.page - 1) * pageinfos.limit; // 像后端请求数据时发送的当前页
this.searchForm.limit = pageinfos.limit; // 请求数据时发送的每页数量
this.loadData(); // 调用请求函数
}
}
pagination.vue说明:
- 接收的props:
- total: 表格数据总的count
- page: 当前页码--是个可以被改变的值,需要通过update:page改变父组件的page
- limit: 当页条数-同page
- pageSizes: 条数选择。类型为数组
- layout:需要显示的内容
- autoScroll: 当前页码或者条数改变的时候是否回到表格顶部
- current-page/page-size 当前页和每页显示条目个数使用计算属性原因:
这里的page/pageSize显示效果是父组件传递过来的page是几,分页就定位在第几页,但是当页码发生改变的时候,就需要传递给父组件去改变page的值,使用计算属性的get分别表示从父组件拿到值,set:去通过update:page改变父组件的page值, 相应的父组件需要设置.sync
- handleSizeChange/handleCurrentChange
传递给父组件的方法,参数是当前的页码和条目个数,父组件接收这个方法之后去改变传递给后端参数中的offset/limit,接着去LoadData()从而拿到所需要的数据。
3. 第三部分:-结合
<template>
<div>
<pipeline-search
@filterSearch="filterSearch"
>
</pipeline-search>
<pipeline-table
:tableData="tableData"
:loading="loading"
@tableChange="tableChange"
@refresh="refresh"
>
</pipeline-table>
<Pagination
style="text-align: right;margin-top: 20px;"
:total="total"
:page.sync="pipelinePage"
:limit.sync="pageSize"
@pagination="pagination"
>
</Pagination>
</div>
</template>
data() {
tableData = [];
loading = false;
total = 0;
pipelinePage = 1;
pageSize = 20;
searchForm: SearchConent = {
offset: (this.pipelinePage - 1) * this.pageSize,
limit: this.pageSize,
search: null,
};
}
created() {
this.loadData();
}
methods: {
async loadData() {
this.loading = true;
const data = await getPipelineList(this.searchForm);
this.tableData = data.results;
this.total = data.count;
this.loading = false;
}
// 点击搜索的时候调用的方法
filterSearch(formInline: SearchConent) {
this.searchForm.search = formInline.search;
this.clearPage(); // 我通常在搜索的时候将此时的page设置为初始值
this.loadData();
}
clearPage() {
this.searchForm.offset = 0; // 将给后端发送的offset设置为0
this.pipelinePage = 1; // 将此时的page设置为1
}
// 当页页/条数发生变化的时候调用的函数
pagination(pageinfos: any) {
this.searchForm.offset = (pageinfos.page - 1) * pageinfos.limit;
this.searchForm.limit = pageinfos.limit;
this.loadData();
}
}