分页器用来做些什么?
首先我们需要明白的是,我们前端工作是向后端发送请求,然后获取相应的数据后在页面上进行展示。那么如果后端传递过来的数据非常的多,如果一次性全部展示这些数据,那么会出现页面带宽消耗大,页面加载缓慢,除此之外并不是所有的数据用户都需要,那么就造成了资源的浪费,而引入分页器的话就可以限制每一页展示的数据,用户可以根据需要来进行切换。
分页器组件的封装
- 首先需要明白几个问题:
- 当前是第几页?
- 总共多少条数据?
- 每一页展示多少数据?
- 连续的页数是多少?
- 总的页数?
- 其中连续的页数是多少?完成这个内容的计算,那么分页器就完成了一半。
- 首先要明白什么是连续的页?
- 其实就是在分页器中连续存在的页,比如:下图红色矩形框中的就属于连续的页。
- 在代码中有相应的文字解释,这儿不过多赘述
- 首先要明白什么是连续的页?
效果展示:
代码如下:
<template>
<div class="page">
<button
@click="sendPageNo(currentPageNo - 1)"
:disabled="currentPageNo==1"
>上一页</button>
<button
:class="{active:currentPageNo==1}"
v-if="startAndEndPageNum[0] > 1"
@click="sendPageNo(1)"
>1</button>
<button v-if="startAndEndPageNum[0]>2">...</button>
<button
v-for="(end,index) in startAndEndPageNum[1]"
:key="index"
v-show="end >= startAndEndPageNum[0]"
:class="{active:currentPageNo==end}"
@click="sendPageNo(end)"
>{{end}}</button>
<button v-if="startAndEndPageNum[1]<totalPages-2">...</button>
<button
:class="{active:currentPageNo==totalPages}"
v-if="startAndEndPageNum[1] < totalPages"
@click="sendPageNo(totalPages)"
>{{totalPages}}</button>
<button
@click="sendPageNo(currentPageNo+1)"
:disabled="currentPageNo==totalPages"
>下一页</button>
</div>
</template>
<script>
export default {
name: 'Pagination',
/**
* currentPageNo: 当前在第几页
total: 总的数据量
pageSize: 每一页多少条数据
continuousPage: 连续的页数
*/
props: ['currentPageNo','total','pageSize','continuousPage'],
computed: {
// 计算出总的页数
/**
* 例如:总的数据量为:81 每一页的展示数据为:3
* totalPages: 81/3 = 26....3
*
* 向上取整的原因:
* 计算出的结果为:26页,回推一步那么可以展示的数据为78
* ,那就是还需要一页才能展示完毕,所以需要向上取整
*/
totalPages(){
return Math.ceil( this.total / this.pageSize );
},
// 起始的页码和终止的页码
startAndEndPageNum(){
const {continuousPage, totalPages, currentPageNo} = this;
// 用于记录开始页码和终止页码
// 起始的值和终止的值
let start = currentPageNo - parseInt(continuousPage / 2);
let end = currentPageNo + parseInt(continuousPage / 2);
// 如果连续的页码大于等于总页码
if(continuousPage >= totalPages){
start = 1;
end = totalPages;
}
// 判断起始的页码和终止的页码
// 起始的页码不能小于1,因为页码不能出现0页吧
if (start < 1){
start = 1;
end = continuousPage;//保证连续的页数
}
// 终止的页码,不能超出总的页数
if(end > totalPages){
/**
* 28 29 30(current) 31 32
*/
start = start - (end - totalPages);//保证连续的页数
end = totalPages;
}
return [start,end];
}
},
methods: {
// 用于其他组件引用时,发送当前点击的页吗
sendPageNo(pageNo){
// getPageNo(pageNo);
this.$emit('getPageNo',pageNo)
}
},
}
</script>
<style scoped>
.page {
text-align: center;
margin-top: 100px;
}
.page>button {
margin: 0 3px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
}
/* 设置拥有disabled属性的按钮的鼠标样式 */
.page>button[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
.page>button.active {
background-color: #409eff;
color: #fff;
}
</style>
App.vue中测试代码:
<template>
<!--
以下数据为测试数据
currentPageNo: 30 当前第几页
total: 91 总共的数据条数
pageSize: 3 每一页多少条数据
continuousPage: 5 连续的页码数
-->
<!-- getPageNo这个自定义事件,作用是发送网络请求改变currentPageNo
-->
<!-- <Pagination
:currentPageNo="31"
:total="91"
:pageSize="3"
:continuousPage="5"
@getPageNo="getPageNo"
/> -->
<Pagination
:currentPageNo="currentPageNo"
:total="91"
:pageSize="3"
:continuousPage="5"
@getPageNo="getPageNo"
/>
</template>
<script>
import Pagination from './components/pagination'
export default {
name: 'App',
data() {
return {
currentPageNo: 1
}
},
components: {
Pagination
},
methods: {
getPageNo(pageNo){
this.currentPageNo = pageNo;
}
},
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
</style>