首先就是自带新建一个组件,名字就叫做PageTable,分页封装template里面很简单,表格放上表格和分页。自带既然表格默认带有分页,分页封装分页的表格数据就放在组件内部
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="page.current"
:page-size.sync="page.size"
:total="page.total"
/>
export default {
name: PageTable,
data() {
return {
page: {
current: 1,
size: 10,
total: 0
},
}
},
}
</script>之后开始思考一个问题,就是自带表格的数据是从父组件传进来,还是分页封装放在组件自身。如果放在父组件里面,表格那么分页的自带变化每次都要emit事件通知父组件,这样我们把分页和表格合在一起就失去了意义,分页封装所以表格的表格数据是要放在组件自身的。
表格数据放在自身,自带父组件就需要传进来一个获取数据的分页封装方法,就叫做fetchData吧,表格在组件内部调用这个方法,就可以获取数据了。这个方法是需要知道当前分页的,并且返回数据和总条数,亿华云由此就可以定义fetchData了
interface ResponseStructure {
data: any[];
total: any;
}
interface fetchData {
(current: number, size: number): Promise
}现在我们的组件已经变成了这个样子
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="page.current"
:page-size.sync="page.size"
:total="page.total"
@size-change="search"
@current-change="getTableData"
/>
export default {
name: PageTable,
props: {
fetchData: {
type: Function,
required: true
},
},
data() {
return {
page: {
current: 1,
size: 10,
total: 0
},
tableData: []
}
},
methods: {
search() {
this.page.current = 1
this.getTableData()
},
async getTableData() {
try {
const { current, size } = this.page
const { data, total } = await this.fetchData(current, size)
this.tableData = data
this.page.total = total
} catch (err) {
this.tableData = []
this.page.total = 0
}
},
}
}
</script>表格一般都会带有搜索项,搜索参数等在父组件定义,并且逻辑写在fetchData里即可,组件内部只处理通用的逻辑。父组件里点击了搜索按钮,是要触发获取事件的,父组件可以通过$refs调用组件内部方法。目前我们定义了两个方法search与getTableData,点击搜索调用search就可以了,并且会自动重置分页,如果有不想重置分页的情况,可以调用getTableData。
目前为止,数据我们已经有了,但是并没有展示,因为element-ui的列信息(Table-column)是通过插槽的,我们使用slot接收一下就可以了
</el-table>到了这里基本逻辑已经完成了,再进一步,一般我们的表格需要loading,loading应该由父组件自己决定如何使用,但是源码下载状态的改变由本组件处理,这里可以使用.sync修饰符,loading逻辑加在 getTableData中即可
export default {
props: {
loading: {
type: Boolean,
default: false,
},
},
methods: {
async getTableData() {
try {
const { current, size } = this.page
this.$emit(update:loading, true)
const { data, total } = await this.fetchData(current, size)
this.tableData = data
this.page.total = total
} catch (err) {
this.tableData = []
this.page.total = 0
} finally {
this.$emit(update:loading, false)
}
},
}
}
</script>loading也加完了,功能就已经完成了,但是还存在一些问题,el-table有很多的Attributes、Events和Methods,Attributes和Events我们透传给el-table即可,Methods需要el-table的ref,如果父组件直接使用ref,获取的是组件外层的div,无法获取到el-table的ref,我们暴露一个方法抛出el-table的ref即可
export default {
methods: {
getTableRef() {
return this.$refs.tableRef
}
}
}
</script>至此,PageTable就写完了,完整代码如下
v-bind="$attrs"
v-on="$listeners"
ref="tableRef"
:data="tableData"
@sort-change="sortChange"
>
layout="total, sizes,prev, pager, next, jumper"
:current-page.sync="page.current"
:page-sizes="pageSizes"
:page-size.sync="page.size"
:total="page.total"
@size-change="search"
@current-change="getTableData"
/>
export default {
name: PageTable,
props: {
/
*** 获取表格数据的请求方法
* @param { Number} current 当前页数
* @param { Number} size 每页条数
* @param { Object} sort 排序
* @param { String} sort.orderBy 排序的key
* @param { (ascending|descending|null)} sort.rule 排序的规则
*/
fetchData: {
type: Function,
required: true
},
pageSizes: {
type: Array,
default: () => [ 10, 20, 50, 100, 150 ]
},
loading: {
type: Boolean,
default: false
},
},
data() {
return {
page: {
current: 1,
size: 10,
total: 0
},
tableData: [],
sort: {
orderBy: ,
rule:
}
}
},
created() {
this.getTableData()
},
methods: {
/** 搜索,可通过 $refs 调用此方法 */
search() {
this.page.current = 1
this.getTableData()
},
/** 获取表格数据,可通过 $refs 调用此方法 */
async getTableData() {
try {
const { current, size } = this.page
this.$emit(beforeFetch)
this.$emit(update:loading, true)
const { data, total } = await this.fetchData(current, size, this.sort)
this.$emit(fetched, data)
this.tableData = data
this.page.total = total
} catch (err) {
this.$emit(fetched, [])
this.tableData = []
this.page.total = 0
} finally {
this.$emit(update:loading, false)
}
},
/** 获取el-table的ref,可通过 $refs 调用此方法 */
getTableRef() {
return this.$refs.tableRef
},
sortChange({ prop, order }) {
this.sort = {
orderBy: prop,
rule: order ||
}
this.getTableData()
}
}
}
</script>网站模板