自定义分页

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()
 }
}```

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值