整篇分两个部分:
思路部分:讲解怎么实现分页器组件【大把时间看-建议】
后面部分:按照步骤,直接引入组件【没有时间看-建议】
<!-- 分页器 -->
<Pagination
:pageNo="searchParams.pageNo"
:pageSize="searchParams.pageSize"
:total="total"
:continues="5"
@getPageNo="getPageNo"
/>
1、通过props取得 Search组件传递的参数
props: ["pageNo", "pageSize", "total", "continues"],
2、**在分页器组件计算属性computed中计算总共多少页/最后一页 - this.total / this.pageSize**
【记得向上取整Math.ceil(),例:当总的数据total=30,每页的数据pageSize=3,那么10页刚刚好展示完毕,如果每页的数据pageSize=4,有7页展示4条数据,还有2条需要下一页展示,所以进行取整,Math.ceil(30/4)=8】
3、**在分页器组件计算属性computed中计算连续页码【至少5页】的起始数字start、结束数字end【当前页pageNo在连续页码中】**
- 上一页:如果当前页pageNo=1,就不显示上一页按钮,绑定点击事件,点击触发getPageNo自定义事件,把当前页pageNo-1当参数传递回search组件,请求上一页的数据
- 第一页:如果连续页码的起始数字start>1,就显示前面定义好的第一页;小于的话,显示连续页码中的第一页按钮。点击事件同上,由于可能处理选中状态,所以绑定一个类【已经在css中定义好的】,添加选中颜色,当然需要判断是否是选中的页
- 省略...小点:当连续页码的start=3时,显示,也就表示,他们之间还有一页
- 连续页码:通过v-for遍历数字,遍历连续页码中end,并判断其中的元素page>start,才显示【因为传过来的连续页码为5,所以在分页器中连续页码出现最大的就是end-start=5,去掉start之前的页码,才能使连续页码为5】,其他同上
- 省略...小点 | 最后一页 | 下一页:计算同上【totalPage是上面已经算完的总页数|最后一页】
<template>
<div class="pagination">
<button>1</button>
<button>上一页</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>
注意:一般使用分页器组件的地方有很多,所以我把他注册为了全局组件
【当前页码pageNo】、【每页展示的数据pageSize】、【总的数据total】、【连续的页码(重要)】,定义一个【自定义事件getPageNo】把用户点击的【当前页码pageNo】传递回来,并进行数据请求
<template>
<div class="pagination">
<button :disabled="pageNo == 1" @click="$emit('getPageNo', pageNo - 1)">
上一页
</button>
<button
v-if="startNumAndEndNum.start > 1"
@click="$emit('getPageNo', 1)"
:class="{ active: pageNo == 1 }"
>
1
</button>
<button v-if="startNumAndEndNum.start > 2">···</button>
<!-- 连续的页码 -->
<button
v-for="(page, index) in startNumAndEndNum.end"
:key="index"
v-if="page >= startNumAndEndNum.start"
@click="$emit('getPageNo', page)"
:class="{ active: pageNo == page }"
>
{{ page }}
</button>
<button v-if="startNumAndEndNum.end < totalPage - 1">···</button>
<button
v-if="startNumAndEndNum.end < totalPage"
@click="$emit('getPageNo', totalPage)"
:class="{ active: pageNo == totalPage }"
>
{{ totalPage }}
</button>
<button
@click="$emit('getPageNo', pageNo + 1)"
:disabled="pageNo == totalPage"
>
下一页
</button>
<button style="margin-left: 30px">共 {{ total }} 条</button>
</div>
</template>
<script>
export default {
name: "Pagination",
props: ["pageNo", "pageSize", "total", "continues"],
computed: {
// *计算总共多少页,也就是最后一页(需要向上取整Math.ceil)
totalPage() {
return Math.ceil(this.total / this.pageSize);
},
// *计算出连续页码的起始数字与结束的数字【连续的页码数字:至少是5】
startNumAndEndNum() {
const { continues, pageNo, totalPage } = this; // 解构了
// 先定义两个变量存储起始数字与结束数字
let start = 0,
end = 0;
// *连续页码数字是5【至少5页】,如果出现不正常现象【不够5页,即总页数 < 连续页码5】
if (continues > totalPage) {
start = 1;
end = totalPage;
} else {
// 正常现象【连续的页码5,但是你的总页数一定是大于5的】 parseInt()返回一个十进制的整数【一个数字的参数可同Math.floor】
start = pageNo - parseInt(continues / 2);
end = pageNo + parseInt(continues / 2);
// 把出现不正常的现象【start数字出现0|负数,continues=5,pageNo=1、2的时候】
if (start < 1) {
start = 1;
end = continues;
}
// 把出现不正常的现象【end数字大于总页码,continues=5,totalPage=30,pageNo=29、30的时候】
if (end > totalPage) {
start = totalPage - continues + 1;
end = totalPage;
}
}
return { start, end };
},
},
};
</script>
<style lang="less" scoped>
.pagination {
text-align: center;
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属性的所有元素
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
</style>
之前手写的python-django框架的分页器 :