分页器在多个组件中都被用到,故注册为全局组件。
1.手写分页器的前提
1.需要知道当前是第几页:pageNo 字段代表当前页数
2.需要知道每一页展示多少条数据:pageSize 字段代表
3.需要知道整个分页器一共有多少条数据:total 字段代表 --- 【获取另外一条信息:一共多少页 Math.ceil(total / pageSize)】 ceil 向上取整
4.需要知道分页器 连续页码 的个数:一般 5 | 7 | 9【奇数】,因为奇数中间对称(美观)
2.手写分页器的代码
新建 Pagination 文件夹,创建 index.vue 文件
index.vue 文件代码:
<template>
<div class="pagination">
<button :disabled="pageNo==1" @click="$emit('getPageNo', pageNo-1)">上一页</button>
<button v-show="startNumAndEndNum.start>1" @click="$emit('getPageNo', 1)" :class="{active: pageNo==1}">1</button>
<button v-show="startNumAndEndNum.start>2">···</button>
<!-- 中间部分 -->
<button v-for="(value, index) in startNumAndEndNum.end" :key="index" v-show="value>=startNumAndEndNum.start"
@click="$emit('getPageNo', value)" :class="{active: pageNo==value}">{{value}}</button>
<!-- 至少中间隔了一个数字,使用 ... -->
<button v-show="startNumAndEndNum.end<totalPage-1">···</button>
<button v-show="startNumAndEndNum.end<totalPage" @click="$emit('getPageNo', totalPage)"
:class="{active: pageNo==totalPage}">{{totalPage}}</button>
<button :disabled="pageNo==totalPage" @click="$emit('getPageNo', pageNo+1)">下一页</button>
<button style="margin-left: 30px">共 {{total}} 条</button>
</div>
</template>
<script>
export default {
name: "Pagination",
props: ['pageNo', 'pageSize', 'total', 'continues'], // 分别表示 第几页,每一页几条数据,共几条数据,连续页码数
computed: {
// 计算出总共多少页
totalPage() {
return Math.ceil(this.total / this.pageSize); // Math.ceil()向上取整
},
// 计算出连续的页面的起始数字和结束数字【连续页码的数字:至少是 5】
startNumAndEndNum() {
const { continues, pageNo, totalPage } = this;
// 先定义两个变量,存储起始的数字与结束的数字
let start = 0, end = 0;
// 连续的页码是 5 【就是至少5页】,如果出现不正常的现象【不够5页】
// 不正常现象【总页数没有连续页码多】
if (continues > totalPage) {
start = 1;
end = totalPage;
} else {
// 正常现象【总页数 > 连续页码】
start = pageNo - parseInt(continues / 2);
end = pageNo + parseInt(continues / 2);
// 把出现不正常的现象【start出现 0 | 负数】纠正
if (start <= 0) {
start = 1;
end = continues;
}
//把出现不正常的现象【end数字大于总页码】纠正
if (end > totalPage) {
end = totalPage;
start = totalPage - continues + 1;
}
}
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] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
.active {
background-color: skyblue;
}
</style>
注意:在使用分页器的父组件中,代码如下(由于触发点击事件后,子组件【分页器组件】需要给父组件【使用分页器的组件】传递信息,在这里使用自定义事件):
<template>
<!-- 分页器:定义自定义事件 getPageNo 以便子组件【分页器】给当前组件传递信息,
该自定义事件的回调函数为 getPageNo,写在该组件当中 -->
<Pagination :pageNo="searchParams.pageNo" :pageSize="searchParams.pageSize" :total="total" :continues="5" @getPageNo="getPageNo" />
</template>
<script>
import { mapState, mapGetters } from 'vuex'
import SearchSelector from './SearchSelector/SearchSelector'
export default {
name: 'Search',
data() {
return {
// 带给服务器的参数
searchParams: {
// 一级分类的ID
"category1Id": "",
// 二级分类的ID
"category2Id": "",
// 三级分类的ID
"category3Id": "",
// 选择分类的 名字
"categoryName": "",
// 关键字
"keyword": "",
// 排序 初始状态应该是 综合、降序
"order": "1: desc",
// 分页器用的参数,代表当前是第几页
"pageNo": 1,
// 代表每一页展示数据的个数
"pageSize": 10,
// 平台售卖属性 带的参数
"props": [],
// 品牌
"trademark": ""
}
}
},
// 组件挂载时执行一次,仅仅执行一次
mounted() {
// 在发请求之前,带给服务器的searchParams参数发生变化,有数值带给服务器
this.getData();
},
methods: {
// 向服务器发请求获取search模块的数据【根据参数不同,返回不同的数据 进行展示】
// 把这次请求封装成一个函数,在需要调用的时候,调用即可
getData() {
this.$store.dispatch('getSearchList', this.searchParams);
},
// 自定义事件的回调函数,获取当前第几页
getPageNo(pageNo) {
// console.log(pageNo);
// 整理带给服务器的参数
this.searchParams.pageNo = pageNo;
this.getData();
}
},
}
</script>