Vue自定义组件开发:使用v-model封装el-pagination组件
1、前言
通过封装el-pagination组件开发自定义分页组件的类似文章网上已经有很多了,但看了一圈,总是不如意,于是决定还是自己动手搞一个。
2、背景
2.1、常规分页处理方法
利用el-pagination组件的常规做法如下:
模板部分:
<el-pagination @size-change="handlesizechange" @current-change="handlecurrentchange" :current-page="pageinfo.pagenum" :page-sizes="[5, 10, 15, 20]" :page-size="pageinfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="pageinfo.total" background> </el-pagination>
脚本部分:
export default { data() { return { formdata : { //查询信息 queryinfo:{ usertype : 0, deleteflag: 2, //表示所有类型 pagenum : 1, pagesize : 10 }, // 用户类型选择框当前选中显示标签值 usertypelabel : "所有类型", // 用户状态选择框当前选中显示标签值 userstatuslabel : "所有类型" }, // 分页信息 pageinfo:{ pagenum : 1, pagesize : 10, total : 0 } } }, methods: { // 查询用户信息列表 queryusers(){ let _this = this; //console.log(this.pageinfo); this.formdata.queryinfo.pagenum = this.pageinfo.pagenum; this.formdata.queryinfo.pagesize = this.pageinfo.pagesize; this.instance.queryusers( this.$baseurl,this.formdata.queryinfo ).then(res => { //console.log(res.data); if (res.data.code == this.global.sucessrequstcode){ //如果查询成功 _this.pageinfo.total = res.data.data.length; _this.userinfolist = res.data.data; }else{ alert(res.data.message); } }).catch(error => { alert('查询失败!'); console.log(error); }); }, // 每页条数改变 handlesizechange(newsize) { this.pageinfo.pagesize = newsize; this.queryusers(); }, // 当前页码改变 handlecurrentchange(newpage) { this.pageinfo.pagenum = newpage; this.queryusers(); } }
2.2、问题分析
每个分页查询,都需要这么来一套,有点简单重复,又略有不同,即查询数据的方法会不同。
对于有强迫症的程序猿来说,简单重复的代码无疑非常令人不爽。因此,需要将之组件化。
分析el-pagination分页组件:
- 有三个核心属性参数,分别是:当前页码(current-page)、每页条数(page-size)、总记录条数(total)。核心属性参数通过绑定父组件页面数据,实行双向联动。其中当前页码和每页条数一般通过操作分页子组件来改变,总记录条数通过查询数据后由父组件进行设置。
- 有两个事件:分别是:@size-change(每页条数改变事件)、@current-change(当前页码改变事件)。这两个事件,分别绑定父组件的对应事件处理方法handlesizechange和handlecurrentchange,两者均调用查询数据的方法,查询数据的方法中,得到结果集后,设置总记录条数。
自定义分页组件的开发目标:消除父组件的handlesizechange和handlecurrentchange的绑定事件方法。
思路:使用v-model绑定分页信息对象,分页信息对象包括3个核心属性参数,即上述的pageinfo。然后分页事件直接绑定查询数据的方法。
3、方案实施
3.1、自定义分页组件
编写一个自定义分页组件代码,文件为/src/pagination.vue。代码如下:
<template lang="html"> <div class="pagination"> <el-pagination @size-change="handlesizechange" @current-change="handlecurrentchange" :current-page.sync="pageinfo.pagenum" :page-size="pageinfo.pagesize" :page-sizes="pagesizes" :total="pageinfo.total" layout="total, sizes, prev, pager, next, jumper" background > </el-pagination> </div> </template> <script> export default { name : "pagination", model : { prop : 'pageinfo', event : 'change' }, props : { // 每页条数选择项 pagesizes: { type: array, default() { return [5, 10, 15, 20]; } }, // v-model绑定的数据对象 pageinfo: { type: object, reuqired:true } }, data(){ return { } }, methods: { handlesizechange(newsize) { var newvalue={ pagesize : newsize, pagenum : newsize <= this.total ? 1 : this.pageinfo['pagenum'] }; this.$emit('change',object.assign(this.pageinfo,newvalue)); this.$emit('pagination'); }, handlecurrentchange(newpage) { this.$emit('change',object.assign(this.pageinfo,{pagenum : newpage})); this.$emit('pagination'); } } } </script> <style lang="css" scoped> .pagination { padding: 10px 0; text-align: center; } </style>
自定义分页组件,名称为pagination,其使用v-model,实现双向数据通信。当页码或每页条数改变时,触发分页事件@pagination,提供与父组件方法绑定。
此处约定了pageinfo的字段结构如下:
pageinfo:{ pagenum : 1, //number pagesize : 10, //number total : 0 //number }
父组件必须提供相同结构的数据对象来绑定组件内部的pageinfo对象。
3.2、注册分页组件
然后注册此分页组件,在main.js中加入下列代码:
import pagination from '@/components/pagination.vue' // 注册分页插件 vue.component('pagination', pagination)
3.3、父组件调用方法
用pagination组件修改前面第二章的代码。
模板部分:
<!-- 分页区域 --> <pagination v-model="pageinfo" @pagination="queryusers"></pagination>
脚本部分:
export default { data() { return { formdata : { //查询信息 queryinfo:{ usertype : 0, deleteflag: 2, //表示所有类型 pagenum : 1, pagesize : 10 }, // 用户类型选择框当前选中显示标签值 usertypelabel : "所有类型", // 用户状态选择框当前选中显示标签值 userstatuslabel : "所有类型" }, // 分页信息 pageinfo:{ pagenum : 1, pagesize : 10, total : 0 } } }, methods: { // 查询用户信息列表 queryusers(){ let _this = this; //console.log(this.pageinfo); this.formdata.queryinfo.pagenum = this.pageinfo.pagenum; this.formdata.queryinfo.pagesize = this.pageinfo.pagesize; this.instance.queryusers( this.$baseurl,this.formdata.queryinfo ).then(res => { //console.log(res.data); if (res.data.code == this.global.sucessrequstcode){ //如果查询成功 _this.pageinfo.total = res.data.data.length; _this.userinfolist = res.data.data; }else{ alert(res.data.message); } }).catch(error => { alert('查询失败!'); console.log(error); }); } }
这样,就去掉了handlesizechange和handlecurrentchange事件响应方法了。分页信息发生改变时,触发绑定的queryusers方法。
另外,如需调整pagesizes,则在模板处类似如下设置:
:pagesizes=[10,20,30,50,100]
4、参考文章
此组件开发主要参考了下列文章:
- vue+el-pagination二次封装,https://blog.csdn.net/weixin_47259997/article/details/107887823。
- vue项目 使用elementui中的el-pagination封装公用分页组件,https://www.jianshu.com/p/e241e5710fb0/。
上一篇: 擅自将快件放快递箱最高罚3万元,快递又要送上门了?
下一篇: 接口隔离原则