本文已参与「新人创作礼」活动,一起开启掘金创作之路。
封装分页器组件:知道四大条件
- 分页器一共需要展示多少条数据total: 100
- 每一个需要展示几条数据pageSize: 3
- 当前在第几页pageNo:6
- 需要知道分页器中间连续五个数字pageCount【一般都是奇数:5,7,9,11】:5
举例子:算算这五个数字是谁?
当前pageNo -> 6
4 5 [6] 7 8
当前pageN0 -> 20
18 19 [20] 21 22
当前pageNo -> 1
-1 0 [1] 2 3 错误的,分页器不可能出现0|负数
【1】 2 3 4 5 正确的
当前pageNo -> 2
0 1 [2] 3 4 错误的
1 [2] 3 4 5 正确的
当前pageNo -> 3
1 2 [3] 4 5
当前pageNo -> 34
32 33 [34] 35 36 错误的,一共34
30 31 32 33 [34] 正确
当前pageNo -> 33
31 32[33] 34 35 错误的
30 31 32 [33] 34 正确的
当前pageNo -> 32
30 31 [32] 33 34 正确的
实现分页器的步骤
第一步:先实现分页器静态组件(HTML + CSS)。如下
<template>
<div class="pagination">
<button>上一页</button>
<button>1</button>
<button>···</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>7</button>
<button>···</button>
<button>9</button>
<button>下一页</button>
<button style="margin-left: 30px">共 60 条</button>
</div>
</template><script>
export default {
name: "Pagination",
};
</script><style lang="less" scoped>
.pagination {
button {
margin: 0 5px;
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] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
</style>
第二步:设置分页器组件为全局组件
第三步:封装分页器需要四大条件[总条数:total、一页显示几条数据:pageSize、连续页码数pageCount:5|7|9、当前页码:pageNo]----在App.vue测试
第四步:计算出总页数[total/pageSize,向上取证]
第五步:算出连续页码起始数字与结束数组【startAndEnd】
注意:特殊,总页数比连续页码数都少 总页数大于连续页码数【正常情况:约束头、尾部的范围:不能出现负数、不能大于总页数】
第六步:连续页码数【5,6,7,8,9】计算出来,把分页器中间、前面、后面结构动态生成 [前面结构1...,后面结构...总页数]什么时候显示、隐藏
第七步:模拟父子组件通信[分页器子组件需要给父组件传递搜索的条件],需要把子组件选中的页码通过自定义事件传递给父组件!!!
第八步:父组件接受参数,整理参数,再次发请求即可【search测试即可】
完成后的代码如下:
<template>
<div class="pagination">
<h1>{{ startAndEnd }}</h1>
<button @click="$emit('currentPage',pageNo - 1)" :disabled="pageNo==1">上一页</button>
<button v-if="startAndEnd.start > 1" @click="$emit('currentPage',1)">1</button>
<button v-if="startAndEnd.start > 2">.....</button>
<!-- 中间连续页码的地方:v-for、数组、对象、数字、字符串 -->
<button v-for="page in startAndEnd.end" :key="page" v-if="page >= startAndEnd.start" @click="$emit('currentPage',page)" :class="{active:pageNo==page}">{{ page }}</button>
<button v-if="startAndEnd.end < totalPage - 1 ">......</button>
<button v-if="startAndEnd.end < totalPage" @click="$emit('currentPage',totalPage)">{{ totalPage }}</button>
<button @click="$emit('currentPage',pageNo + 1)" :disabled="pageNo==totalPage">下一页</button>
<button style="margin-left: 30px">共 {{ total }} 条</button>
</div>
</template>
<script>
export default {
name: "Pagination",
props: ["total", "pageSize", "pageNo", "pagerCount"],
computed: {
//分页器一共多少页【总条数/每页展示条数】
totalPage() {
//向上取整数
return Math.ceil(this.total / this.pageSize);
},
//底下的代码是整个分页器最重要的地方[算出连续五个数字、开头、结尾]
startAndEnd() {
//算出连续页码:开始与结束这两个数字
let start = 0,
end = 0;
const { totalPage, pagerCount, pageNo } = this;
//特殊情况:总共页数小于连续页码数
if (totalPage < pagerCount) {
start = 1;
end = totalPage;
} else {
//正常情况:分页器总页数大于连续页码数
start = pageNo - parseInt(pagerCount / 2);
end = pageNo + parseInt(pagerCount / 2);
//约束start|end在合理范围之内
//约束头部
if (start < 1) {
start = 1;
end = pagerCount;
}
//约束尾部
if (end > totalPage) {
end = totalPage;
start = totalPage - pagerCount + 1;
}
}
return { start, end };
},
},
};
</script>
<style lang="less" scoped>
.pagination {
button {
margin: 0 5px;
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] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
</style>
在别的组件中使用分页器组件:
<Pagination
:total="100"
:pageSize="10"
:pageNo="6"
:pagerCount="5"
@currentPage="currentPage"
></Pagination>
methods: {
currentPage(curPage){
console.log(curPage);
},
}
\