实现的效果
当时因为下拉框中的数据过多,所以想到使用分页的方式来实现。
现在来看看具体的实现吧。
准备分页的组件
分页组件的代码是从网上拼凑的,代码如下:
<template> <el-select v-model="childSelectedValue" :filterable="remote" multiple :loading="loading" :remote="remote" :size="size" :remote-method="remoteMethod" :clearable="clearable" @change="handleChange" @clear="handleClear" @focus="handleFocus" :style="{width: '93%'}" :placeholder="placeholder"> <el-option v-for="item in optionSource" :key="item[valueKey]" :label="item[labelKey]" :value="item[valueKey]"> </el-option> <el-pagination small layout="prev, pager, next" @current-change="changeNumber" :hide-on-single-page="true" :page-size="paginationOption.pageSize" :current-page="paginationOption.currentPage" :pager-count="paginationOption.pagerCount" :total="paginationOption.total"> </el-pagination> </el-select> </template> <script> export default { name: 'PaginationSelect', props: { //此参数只是为了父组件实现 v-model指令接受参数用,子组件中无实际意义 // 在子组件中通过监听childSelectedValue值,来触发 input 事件,实现子父组件数据绑定 value:{ type:String, default: '' }, valueKey:{//传入的option数组中,要作为最终选择项的键值名称 type:String }, labelKey:{//传入的option数组中,要作为显示项的键值名称 type:String }, clearable :{//是否支持清除,默认支持 type:Boolean, default:true }, remote:{//是否支持远程搜索,默认支持 type:Boolean, default:false }, size:{//组件尺寸,配置项同select String | medium/small/mini type:String, default:'medium' }, loading:{//远程数据加载状态显示 type:Boolean, default:false }, placeholder :{ type:String, default:'给谁用' }, optionSource:{//下拉框组件数据源 type:Array, required:true }, paginationOption:{//分页配置项 type:Object, default:function () { return { pageSize:5,//每页显示条数 6条刚好 currentPage:1,//当前页 pagerCount:5,//按钮数,超过时会折叠 total:10 //总条数 } } } }, data () { return { childSelectedValue:this.value, } }, watch:{ //监听子组件中选择的值得变化,每当选择一个项后,触发input事件, // 将子组件中选择的值通过input事件传递给父组件,实现父组件中v-model绑定的值的双向绑定 childSelectedValue(val){ this.$emit("input",val); }, value(val){ if(val!=null && val.length<1){ this.childSelectedValue = ''; } } }, mounted(){ }, methods:{ //子组件分页器,页码选择事件,父组件中监听子组件的 pageNationChange 事件,获取当前页码 changeNumber(val){ //此处的val是页码 this.$emit("pageNationChange",val); }, // 远程调用方法,在父组件中实现远程方法 remoteMethod(val){ if(val!=null && val.length>0){ //只有输入的字符串长度大于1时,触发 this.$emit("remote-method",val); }else{ this.childSelectedValue = ' ' } }, //使组件支持change事件 handleChange(val){ this.$emit("change",val); }, //使组件支持clear事件 handleClear(val){ this.$emit("clear",val); }, //解决远程搜索无结果时,显示清除按钮问题 handleFocus(){ if(this.childSelectedValue.length<1){ this.childSelectedValue = '' } } } } </script> <style scoped> </style>
关键代码都有注释,所以这里就不过多解释。直接放到项目中即可使用,下面再来看看怎么使用。
父组件的写法
父组件中的代码,网上不全,基本上都是自己整理的,首先在需要写下拉列表的地方写:
<!--添加人员 --> <el-form-item label="选择人员" > <pagination-select @pageNationChange="pageNationChange" @change="getAthIdsAdd" :optionSource="athListAllByLocal" v-model="fanganform.pbeizhu" labelKey="aname" valueKey="id" :paginationOption="setSelectPage" > </pagination-select> </el-form-item>
pageNationChange
为下拉列表分页的点击事件,执行的方法如下:
//下拉列表分页的点击的事件 pageNationChange(val){ //设置当前页为点击的页 this.setSelectPage.currentPage = val; //重新调用分页查询的方法 this.getAthListLocal(this.setSelectPage); },
change
为下拉列表选项的改变事件,执行方法如下:
//获取下拉框中的运动员编号--保存方案 getAthIdsAdd(val){ var names = ""; for(let i=0;i<=val.length-1;i++){ this.athListAllPaged.find((item)=>{ if(item.id === val[i]){ names+=item.aname+","; } }); } console.log(names); this.fanganform.ppersons = names; },
因为我需要把值和名称都存在数据库中,所以这里需要根据id
来遍历一下name
的值。
optionSource
为下拉列表中的数据源。
paginationOption
为分页的属性,代码如下:
//分页信息 setSelectPage:{ pageSize:6,//每页显示条数 3条刚好 currentPage:1,//当前页 pagerCount:5,//按钮数,超过时会折叠 total:0 //总条数 },
分页查询信息的代码如下:
//查询本地的运动员 getAthListLocal(setSelectPage){ getListAthPage(setSelectPage.currentPage,setSelectPage.pageSize).then(res => { const data = res.data.data; //下拉列表数据源绑定 this.athListAllByLocal =data.records; //绑定总记录数 this.setSelectPage.total = data.total; // if(this.athListAllPaged.length===0){ this.athListAllPaged=data.records; }else { //追加数据 for(let i = 0;i<data.records.length;i++){ this.athListAllPaged.push(data.records[i]); } } }); },
如果需要更改分页的的按钮数和页大小,可以直接修改setSelectPage
中的pageSize
和pagerCount
即可。
最后的效果就实现了。