分页功能
- 分页器的优点
- 实现分页功能
- 自定义分页器
- 先实现静态分页器调试
- 分页器动态数据/交互
- Element UI组件
分页器的优点
电商平台同时展示的数据很多,所以采用分页功能
实现分页功能
Element UI已经有封装好的组件,但是也要掌握原理,以及自定义的分页器实现!
所以从两个方面实现:自定义和Element UI
自定义分页器
实现前需要数据:
- 当前在第几页——
pageNo
- 每页展示多少条数据——
pageSize
- 整个分页器一共有多少条数据——
total
(已知pageSize和total就可以知道分几页,需要向上取整
) - 连续的分页个数——
continues
(一般是5|7奇数)
先实现静态分页器调试
分页Pagination组件放在父组件Search,以上数据都需要父组件传给子组件Pagination。
先传入静态数据实现,之后再修改
<!-- Search.vue-->
<!-- 分页器-->
<Pagination :pageNo="1" :pageSize="3" :total="91" :continues="5"/>
静态页面效果
<template>
<div class="fr page">
<div class="sui-pagination clearfix">
<ul>
<li class="prev disabled">
<a href="#">«上一页</a>
</li>
<li class="active">
<a href="#">1</a>
</li>
<li class="dotted"><span>...</span></li>
<!--中间部分遍历-->
<li>
<a href="#">2</a>
</li>
<li>
<a href="#">3</a>
</li>
<li>
<a href="#">4</a>
</li>
<li>
<a href="#">5</a>
</li>
<li class="dotted"><span>...</span></li>
<li class="next">
<a href="#">下一页»</a>
</li>
</ul>
<div><span>共{{totalPage}}页 </span></div>
</div>
</div>
</template>
export default{
name:'Pagination',
//接收父组件Search传递过来的数据
props:['pageNo','pageSize','total','continues'],
computed:{
totalPage(){
return Math.ceil(this.total/this.pageSize);
}
}
}
!(重点)算出连续页面的起始数字和结束数字
- 规律:当前页永远在连续数字的中间
- 当前第八页–> 6 7 8 9 10
- 当前第14页–> 12 13 14 15 16 (当前页pageNo)
- 既然是一串数据,那么就放在一个数组当中?
computed:{
totalPage(){
return Math.ceil(this.total/this.pageSize);
},
startNumAndEndNum(){
//将所用到的组件实例上的数据解构取出来(免得再一次次this.变量)
const {continues,pageNo,totalPage} = this;
//定义两个变量
let start = 0, end = 0;
//正常是continues<totalPage,那么就得单独做一次判断
if(continues>totalPage){
start = 1;
end = totalPage;
}else{
//找规律:continues5页--减2,7页--减3……
start = pageNo - parseInt(continues/2);
end = pageNo + parseInt(continues/2);
//start和end会出现溢出情况!
//分别判断情况
if(start<=0){
start = 1;
end = continues;
}
if(end>totalPage){
end = totalPage;
start = totalPage - continues + 1;
}
}
return {start,end};
},
}
- 动态中间部分遍历
<!--前面部分遍历-->
<li class="prev disabled">
<a href="#">«上一页</a>
</li>
<li class="active">
<a href="#" v-show="start != 1">1</a>
</li>
<li class="dotted" v-show="start != 1"><span>...</span></li>
<!--中间部分遍历-->
<li v-for="(page, index) in startNumAndEndNum.end" :key="index"
v-show="page >= startNumAndEndNum.start">
<a href="#">{{ page }}</a>
</li>
<!--后面部分遍历-->
<li class="dotted" v-show="startNumAndEndNum.end != totalPage" ><span>...</span></li>
<li class="active" v-show="startNumAndEndNum.end != totalPage">
<a href="#">{{ totalPage }}</a>
</li>
<li class="next">
<a href="#">下一页»</a>
</li>
1什么时候显示?如果start是1那么开头的1就不需要了v-show="start!=1"
1后面的省略号也同理,start != 1 则显示
- 当pageNo为1时
后面的31和…也同样需要判断v-show="startNumAndEndNum.end != totalPage"
- 当pageNo为30时
分页器动态数据/交互
点击事件:
pageNo在1时无法点击上一页,pageNo为31时也同样无法点击下一页
li标签设置样式cursor:not-allowed
(会显示一个禁止符合)
如果用的是button标签,可以用disabled属性:disable="pageNo==1"
<li class="prev" :class="{disabled:pageNo==1}">
<a href="#">«上一页</a>
</li>
<li class="prev" :class="{disabled:pageNo==totalPage}">
<a href="#">«下一页</a>
</li>
- 子组件点击事件,会改变pageNo,则需要传递给父组件
-
父组件Search给子组件Pagination传递数据,并在子组件上绑定自定义getPageNo
<Pagination :pageNo=“searchParams.pageNo” :pageSize=“searchParams.pageSize” :total=“total” continues=“5” @getPageNo=“”> -
在子组件中触发事件并传递参数给父组件,父组件拿到参数可修改数据
- 子组件:
- 在上一页按钮上绑定click事件触发
@click="$emit('getPageNo',pageNo-1)"
- 在分页的数字上绑定
@click="$emit('getPageNo',1)"
、@click="$emit('getPageNo',totalPage)"
- 在v-for循环的分页上
@click="$emit('getPageNo',page)"
传递page就行 - 在下一页
@click="$emit('getPageNo',pageNo+1)"
- 在上一页按钮上绑定click事件触发
- 父组件:
-自定义回调函数,传递数据发送分页请求
- 子组件:
getPageNo(pageNo){
this.searchParamse.pageNo = pageNo;
//然后发送请求
}
最后样式部分:可以点击的地方加上类名:class="active:pageNo==1"
,:class="active:pageNo==page"
、:class="active:pageNo==totalPage"
.class{
background:skybule;
}
ok以上就完工啦!
Element UI组件
<el-pagination background layout="prev, pager, next" :total="91">
</el-pagination>