1.分页功能实现
为什么很多项目采用分页功能:比如电商平台同时展示的数据有很多,采用分页功能
2.分液器展示,需要那些数据(条件)
2.1 需要知道当前是第几个:pageNo字段代表当前页数
2.2 需要知道每一个需要展示多少条数据:pageSize字段进行代表
2.3 需要知道整个分页器一共有多少条数据:total字段进行代表—[获取另外一条信息:一共多少页]
2.4 需要知道整个分页器连续的页码数:5|7(奇数),因为奇数对称
总结:对于分页器而言,自定义前提需要知道以上四个条件
3.自定义分页器,在开发的时候先自己传递假的数据进行调试,直到调试成功以后再用服务器数据
由于多个页面都需要分页,我们把分页器设置为一个全局组件
3.1 全局组件Pagination(src/main.js)
(1)引入全局组件
import Pagination from '@/components/Pagination'
(2)注册全局组件
//第一个参数:全局组件的名字,第二个参数:哪一个组件
Vue.component(Pagination.name,Pagination)
3.2 使用Pagination组件(父组件)
父组件将需要的数据以及自定义事件通过props传递给子组件Pagination
<!-- 分页 -->
<Pagination
:pageNo=searchParams.pageNo
:pageSize=searchParams.pageSize
:total='total'
:continues='5'
/>
3.3 全局组件Pagination(子组件)
(1)接收父组件传递过来的数据
props: ['pageNo', 'pageSize', 'total', 'continues']
(2)计算总页数(计算属性)
totalPage() {
// 向上取整
return Math.ceil(this.total / this.pageSize)
},
(3)计算出连续页码的起始数字和结束数字(连续页码的数字至少是5,计算属性)
对于分页器而言,很重要的一个地方即为(算出连续页面的起始数字start和结束数字end
当前是第8页(pageNo) ,连续页码为5(continues)-----6 7 8 9 10
注:分液器数字没有0,也没有负数
start<1:
当前是第1页 连续页码为5----1 2 3 4 5
当前是第2页 连续页码为5----1 2 3 4 5
end>tatolPage:
当前是第31页 连续页码为5—27 28 29 30 31
当前是第30页 连续页码为5—27 28 29 30 31
startNumAndEndNum() {
const { continues, pageNo, totalPage } = this
// 先定义两个变量存储起始数字和结束数字
let start = 0, end = 0;
// 连续页码的数字至少是5(至少5页),如果出现不正常现象(就是不够5页)
// 不正常现象(总页数没有连续页码多)
if (continues > totalPage) {
start = 1;
end = totalPage;
} else {
// 正常现象(连续页码为5,总页数一定是大于5的)
// 起始数字
start = pageNo - parseInt(continues / 2);
// 结束数字
end = pageNo + parseInt(continues / 2);
// 把出现的不正常的现象(start数字出现0|负数)纠正
if (start < 1) {
start = 1;
end = continues;
}
// 把出现的不正常的现象(end数字大于总页码)纠正
if (end > totalPage) {
end = totalPage;
start = totalPage - continues + 1;
}
}
return { start, end }
}
4.分页器动态展示
分为上中下三个部分
v-for:数组|数字|对象|字符串
4.1 从仓库中获取数据
import { mapState } from 'vuex'
computed: {
// 获取search模块展示产品一共多少数据
...mapState({
total: state => state.search.searchList.total
})
},
4.2 向子组件传入自定义事件getPageNo
<Pagination
:pageNo=searchParams.pageNo
:pageSize=searchParams.pageSize
:total='total'
:continues='5'
@getPageNo='getPageNo' />
4.3 父组件中定义自定义事件getPageNo
// 自定义事件回调---获取当前第几页
getPageNo(pageNo) {
console.log(pageNo)
}
4.4 子组件Pagination使用父组件自定义事件
(1)分页结构
(2)前面部分
- 上一页按钮功能:
(1)当在第一页时,按钮无效::disabled="pageNo == 1
(2)点击,emit传入自定义事件getPageNo且pageNo-1:@click="$emit('getPageNo', pageNo - 1)"
(3)完整代码
<button :disabled="pageNo == 1" @click="$emit('getPageNo', pageNo - 1)">上一页</button>
- 第 1 页按钮功能:
(1)当起始页码start > 1 时,此按钮才有效:v-if="startNumAndEndNum.start > 1"
(2)点击,emit传入自定义事件getPageNo且pageNo= 1 :@click="$emit('getPageNo', 1)"
(3)添加一个active类::class="{ active: pageNo == 1 }"
(4)完整代码:
<button v-if="startNumAndEndNum.start > 1" @click="$emit('getPageNo', 1)"
:class="{ active: pageNo == 1 }">1</button>
- 省略按钮功能:
(1)当中间连续页码数为5,且当起始页码start > 2 时,此按钮才有效(显示):startNumAndEndNum.start > 2
(2)完整代码:
<button v-if="startNumAndEndNum.start > 2">···</button>
(2)中间部分(5个连续页)
分页动态展示:利用v-for遍历数字
v-for:可以遍历数组|数字|对象|字符串
- 分页遍历数字
(1)利用v-for遍历数字且key为索引值:v-for="(page, index) in startNumAndEndNum.end" :key="index"
(2)被遍历的数字必须大于起始页页数:v-if="page >= startNumAndEndNum.start"
(3)点击,emit传入自定义事件getPageNo且pageNo= page:@click="$emit('getPageNo', page)"
(4)添加一个active类::class="{ active: pageNo == page }"
(5)完整代码:
<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>
(3)后面部分
- 省略按钮功能:
(1)当中间连续页码数为5,且当结束页码end < totalPage - 1>时,此按钮才有效(显示):startNumAndEndNum.end < totalPage - 1
(2)完整代码:
<button v-if="startNumAndEndNum.end < totalPage - 1">···</button>
- 最后一页按钮功能:
(1)当结束页码end < totalPage 时,此按钮才有效:v-if="startNumAndEndNum.end < totalPage"
(2)点击,emit传入自定义事件getPageNo且pageNo= totalPage:@click="$emit('getPageNo', totalPage)"
(3)添加一个active类::class="{ active: pageNo == totalPage }"
(4)完整代码:
<button
v-if="startNumAndEndNum.end < totalPage"
@click="$emit('getPageNo', totalPage)"
:class="{ active: pageNo == totalPage }">
{{ totalPage }}
</button>
- 下一页按钮功能:
(1)当在最后一页时,按钮无效::disabled="pageNo == totalPage
(2)点击,emit传入自定义事件getPageNo且pageNo+1:@click="$emit('getPageNo', pageNo +1)"
(3)完整代码
<button :disabled="pageNo == totalPage" @click="$emit('getPageNo', pageNo + 1)">下一页</button>
- 总条数
<button style="margin-left: 30px">共{{ total }} 条</button>
Pagination组件完整代码
<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 :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)
},
// 计算出连续页码的起始数字和结束数字(连续页码的数字至少是5)
startNumAndEndNum() {
const { continues, pageNo, totalPage } = this
// 先定义两个变量存储起始数字和结束数字
let start = 0, end = 0;
// 连续页码的数字至少是5(至少5页),如果出现不正常现象(就是不够5页)
// 不正常现象(总页数没有连续页码多)
if (continues > totalPage) {
start = 1;
end = totalPage;
} else {
// 正常现象(连续页码为5,总页数一定是大于5的)
// 起始数字
start = pageNo - parseInt(continues / 2);
// 结束数字
end = pageNo + parseInt(continues / 2);
// 把出现的不正常的现象(start数字出现0|负数)纠正
if (start < 1) {
start = 1;
end = continues;
}
// 把出现的不正常的现象(end数字大于总页码)纠正
if (end > totalPage) {
end = totalPage;
start = totalPage - continues + 1;
}
}
return { start, end }
}
}
}
</script>
5. 父组件中自定义方法getPageNo
// 自定义事件回调---获取当前第几页
getPageNo(pageNo) {
// console.log(pageNo)
// 整理带给服务器的数据
this.searchParams.pageNo = pageNo
// 再次请求数据
this.getData()
}
}```