readme:
方法一:
//index1.vue是一个封装的分页器组件 向子组件传 数据总数量 ,得到 当前页 和 页码尺寸 ,分页处理在当前组件完成。
使用说明:
1、引用并使用组件
2、向子组件传参数: total (数据总数量)
3、用自定义函数接收组件传参 (当前页 currentPage)(页码尺寸 pageSize)
4、计算属性:计算分页后的数据:
代码:
引入子组件:
<Page class="page" :total="total" @get-currentPage="getCurrentPage" @get-pageSize="getPageSize"></Page>
自定义事件回调:
//当前页:
const currentPage = ref(1)
//自定义事件的回调函数 获取当前的页码
const getCurrentPage=(val)=>{
currentPage.value=val
}
//页码尺寸:
const pageSize=ref(5)
//自定义事件的回调函数 获取 页码尺寸
const getPageSize=(val)=>{
pageSize.value=val
}
计算属性:
//计算分好页的数据:
const NewList=computed(()=>{
return studentList.value.slice((currentPage.value-1)*pageSize.value,currentPage.value*pageSize.value)
})
注意:如想修改页码尺寸列表选项 (默认是[5,10,15,20]) 修改子组件中 pageSizeArr 即可
优点:父子组件传递仅为1或2个数字 性能优化好。
缺点:当前组件需写较多代码。
**************************************************************************************************
方法二:
//index2.vue是一个封装的分页器组件 向子组件传 数据列表 ,得到 需要渲染的数据(分页好的数据) ,分页处理在子组件(分页器)完成。
使用说明:
1、引用并使用组件
2、向子组件传参数: list (数据列表)
3、用自定义函数接收组件传参 (分好页的数据 NewList)
代码:
引入子组件:
<Page class="page" :list="studentList" @get-newList="getNewList"></Page>
自定义事件回调:
//分页:
//新列表
const NewList=ref([])
//自定义事件的回调函数 获取 信列表
const getNewList=(val)=>{
NewList.value=val
}
注意:如想修改页码尺寸列表选项 (默认是[5,10,15,20]) 修改子组件中 pageSizeArr 即可
优点:使用简单。
缺点:父子组件传递数组列表(性能可能不如方法一)
index1.vue
<script setup>
import {ref,computed,onMounted} from 'vue'
//接收父组件传来的数据:
const props=defineProps({
total:Number
})
//定义pageSize
const pageSize=ref(5)
// pageSize数组(可选项)
const pageSizeArr=[5,10,15,20]
//连续页码个数:
const continues=5
//当前页:
const currentPage=ref(1)
//总页数:
const pageNum=computed(()=>{
return Math.ceil(props.total / pageSize.value)
})
//连续显示的页码:
const pageStartandEnd=computed(()=>{
let start = 0; //开始页码
let end = 0; //结束页码
if(continues>=pageNum.value){
//连续页码数 大于 总页码数
start = 1;
end = pageNum.value;
}else{
//总页码数 大于 连续页码数
start = currentPage.value - Math.floor(continues / 2);
end = currentPage.value + Math.floor(continues / 2);
if(start<1){
//开始页码小于1
start = 1;
end = continues;
}
if (end > pageNum.value) {
//结束页码大于总页码
start = pageNum.value - continues + 1;
end = pageNum.value;
}
}
return {start,end}
})
//自定义事件:向父组件发送当前页码 与 发送 页码尺寸
const emit =defineEmits(['get-currentPage','get-pageSize']) //生成emit方法
const sendCurrentPage=()=>{
emit('get-currentPage',currentPage.value)
}
const sendPageSize=()=>{
emit('get-pageSize',pageSize.value)
}
//上一页按钮:
const prevPage =()=>{
if(currentPage.value<=1) return
currentPage.value--
sendCurrentPage()
}
//首页按钮:
const firstPage=()=>{
currentPage.value=1
sendCurrentPage()
}
//下一页按钮:
const nextPage =()=>{
if(currentPage.value>=pageNum.value) return
currentPage.value++
sendCurrentPage()
}
//尾页按钮:
const lastPage=()=>{
currentPage.value=pageNum.value
sendCurrentPage()
}
//点击页码按钮:
const clickPage=(val)=>{
currentPage.value=val
sendCurrentPage()
}
//输入框输入页码:
const changePage=(e)=>{
let x=e.target.value;
if (x < 1 || x > pageNum.value) {
currentPage.value=1
return;
}
currentPage.value=Math.ceil(x) //防止输入小数
sendCurrentPage()
}
//修改页码尺寸的回调
const changeSize=()=>{
sendPageSize() //发送页码尺寸
currentPage.value=1 //页码置为1 然后发送
sendCurrentPage()
}
//组件刚加载好就给父组件传递 当前页码 页码尺寸
onMounted(()=>{
sendPageSize()
sendCurrentPage()
})
</script>
<template>
<div class="page">
<div>共{{total}}条</div>
<div>
<select class="select" v-model="pageSize" @change="changeSize($event)">
<option v-for="(item,index) in pageSizeArr" :key="index" :value="item" > {{ item }}条/页</option>
</select>
</div>
<div>
<button @click="prevPage">上一页</button>
<button @click="firstPage" v-if="pageStartandEnd.start>1">1</button>
<button v-if="pageStartandEnd.start>2">...</button>
<button v-for="(page,index) in continues "
:key="index"
:class="{'active':page+pageStartandEnd.start-1===currentPage}"
@click="clickPage(page+pageStartandEnd.start-1)"
>{{ page+pageStartandEnd.start-1 }}</button>
<button v-if="pageStartandEnd.end< pageNum-1">...</button>
<button @click="lastPage" v-if="pageStartandEnd.end< pageNum">{{pageNum }}</button>
<button @click="nextPage">下一页</button>
</div>
<div>
<span>前往</span>
<input type="number" @change="changePage($event)" v-model="currentPage"/>
<span>页</span>
</div>
</div>
</template>
<style scoped lang="scss">
.page {
height: 30px;
width: 700px;
font-size: 13px;
display: flex;
justify-content: space-between;
div {
height: 30px;
line-height: 30px;
}
.select {
height: 25px;
width: 100px;
text-align: center;
}
button {
margin: 0 5px;
background-color: #fff;
cursor: pointer;
border: none;
text-align: center;
}
input {
width: 20px;
border-radius: 5px;
height: 25px;
width: 40px;
margin-left: 5px;
margin-right: 5px;
text-align: center;
}
}
.active{
color: #409eff;
}
/* 去掉input中自带加减号 */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
</style>
index2.vue
<script setup>
import {ref,computed,onUpdated} from 'vue'
//接收父组件传来的数据:
const props=defineProps({
list:Array
})
//获取数据数量:
const total=computed(()=>{
return props.list.length
})
//定义pageSize
const pageSize=ref(5)
// pageSize数组(可选项)
const pageSizeArr=[5,10,15,20]
//连续页码个数:
const continues=5
//当前页:
const currentPage=ref(1)
//总页数:
const pageNum=computed(()=>{
return Math.ceil(total.value / pageSize.value)
})
//连续显示的页码:
const pageStartandEnd=computed(()=>{
let start = 0; //开始页码
let end = 0; //结束页码
if(continues>=pageNum.value){
//连续页码数 大于 总页码数
start = 1;
end = pageNum.value;
}else{
//总页码数 大于 连续页码数
start = currentPage.value - Math.floor(continues / 2);
end = currentPage.value + Math.floor(continues / 2);
if(start<1){
//开始页码小于1
start = 1;
end = continues;
}
if (end > pageNum.value) {
//结束页码大于总页码
start = pageNum.value - continues + 1;
end = pageNum.value;
}
}
return {start,end}
})
//新列表:
const NewList=computed(()=>{
return props.list.slice((currentPage.value-1)*pageSize.value,currentPage.value*pageSize.value)
})
//自定义事件:向父组件发送 分好页的数据
const emit =defineEmits(['get-newList']) //生成emit方法
const sendNewList=()=>{
emit('get-newList',NewList.value)
}
//上一页按钮:
const prevPage =()=>{
if(currentPage.value<=1) return
currentPage.value--
sendNewList()
}
//首页按钮:
const firstPage=()=>{
currentPage.value=1
sendNewList()
}
//下一页按钮:
const nextPage =()=>{
if(currentPage.value>=pageNum.value) return
currentPage.value++
sendNewList()
}
//尾页按钮:
const lastPage=()=>{
currentPage.value=pageNum.value
sendNewList()
}
//点击页码按钮:
const clickPage=(val)=>{
currentPage.value=val
sendNewList()
}
//输入框输入页码:
const changePage=(e)=>{
let x=e.target.value;
if (x < 1 || x > pageNum.value) {
currentPage.value=1
return;
}
currentPage.value=Math.ceil(x) //防止输入小数
sendNewList()
}
//修改页码尺寸的回调
const changeSize=()=>{
currentPage.value=1 //页码置为1 然后发送
sendNewList()
}
//在 onUpdated中 发送 否则刚加载页面的时候不显示数据
onUpdated(()=>{
sendNewList()
})
</script>
<template>
<div class="page">
<div>共{{total}}条</div>
<div>
<select class="select" v-model="pageSize" @change="changeSize($event)">
<option v-for="(item,index) in pageSizeArr" :key="index" :value="item" > {{ item }}条/页</option>
</select>
</div>
<div>
<button @click="prevPage">上一页</button>
<button @click="firstPage" v-if="pageStartandEnd.start>1">1</button>
<button v-if="pageStartandEnd.start>2">...</button>
<button v-for="(page,index) in continues "
:key="index"
:class="{'active':page+pageStartandEnd.start-1===currentPage}"
@click="clickPage(page+pageStartandEnd.start-1)"
>{{ page+pageStartandEnd.start-1 }}</button>
<button v-if="pageStartandEnd.end< pageNum-1">...</button>
<button @click="lastPage" v-if="pageStartandEnd.end< pageNum">{{pageNum }}</button>
<button @click="nextPage">下一页</button>
</div>
<div>
<span>前往</span>
<input type="number" @change="changePage($event)" v-model="currentPage"/>
<span>页</span>
</div>
</div>
</template>
<style scoped lang="scss">
.page {
height: 30px;
width: 700px;
font-size: 13px;
display: flex;
justify-content: space-between;
div {
height: 30px;
line-height: 30px;
}
.select {
height: 25px;
width: 100px;
text-align: center;
}
button {
margin: 0 5px;
background-color: #fff;
cursor: pointer;
border: none;
text-align: center;
}
input {
width: 20px;
border-radius: 5px;
height: 25px;
width: 40px;
margin-left: 5px;
margin-right: 5px;
text-align: center;
}
}
.active{
color: #409eff;
}
/* 去掉input中自带加减号 */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
</style>