• Vue电商项目--分页器制作


    分页器静态组件

    分页这个组件,不单单是一个页面用到了。多个页面同时用它,因此我们可以封装成一个全局组件

    需要将这个分页结构拆分到components 

    通用的分页组件Pagination

    1. <template>
    2. <div class="pagination">
    3. <button>1</button>
    4. <button>上一页</button>
    5. <button>···</button>
    6. <button>3</button>
    7. <button>4</button>
    8. <button>5</button>
    9. <button>6</button>
    10. <button>7</button>
    11. <button>···</button>
    12. <button>9</button>
    13. <button>上一页</button>
    14. <button style="margin-left: 30px">60</button>
    15. </div>
    16. </template>
    17. <script>
    18. export default {
    19. name: "Pagination",
    20. }
    21. </script>
    22. <style lang="less" scoped>
    23. .pagination {
    24. button {
    25. margin: 0 5px;
    26. background-color: #f4f4f5;
    27. color: #606266;
    28. outline: none;
    29. border-radius: 2px;
    30. padding: 0 4px;
    31. vertical-align: top;
    32. display: inline-block;
    33. font-size: 13px;
    34. min-width: 35.5px;
    35. height: 28px;
    36. line-height: 28px;
    37. cursor: pointer;
    38. box-sizing: border-box;
    39. text-align: center;
    40. border: 0;
    41. &[disabled] {
    42. color: #c0c4cc;
    43. cursor: not-allowed;
    44. }
    45. &.active {
    46. cursor: not-allowed;
    47. background-color: #409eff;
    48. color: #fff;
    49. }
    50. }
    51. }
    52. </style>

     然后全局的注册这个组件

     有点小问题,改一下。让它上一页在1前面,和居中 

    排序复习

    1. changeOrder(flag){
    2. let originOrder=this.searchParams.order;
    3. let originFlag=this.searchParams.order.split(":")[0]
    4. let originSort=this.searchParams.order.split(":")[1]
    5. // 准备一个新的order属性值
    6. let newOrder=''
    7. // 点击的是综合
    8. if(flag==originFlag){
    9. newOrder=`${originFlag}:${originSort=='desc'?"asc":"desc"}`
    10. }else{
    11. // 点击的是价格
    12. newOrder=`${flag}:${'desc'}`
    13. }
    14. console.log(newOrder);
    15. // 将新的order赋予searchParams
    16. this.searchParams.order=newOrder
    17. this.getData()
    18. }

    这里要注意的一点就是这个newOrder是会不断的变化

     而这个触发else,就是点击另一个才会触发降序 

    分页功能分析

    1.为什么很多项目采用分页功能,比如电商平台同时展示的数据有很多(1万+),采用分页功能

    ElementUI有相应的分页组件,使用起来超级简单,但是我们不使用【掌握自定义分页功能】

    2.分页展示,需要那些数据(条件)?

    需要知道当前是第几个:pageNo字段代表当前页码

    需要知道每一个需要展示多少条数据:pageSize字段进行代表

    需要知道整个分页器一共有多少条数据:total字段进行代表--【获取另外一条信息:一共多少页】

    需要知道分页器连续页码的个数:5|7【奇数】,以为奇数对称(好看)

     总结:对于分页器而言,自定义前提需要知道四个前提条件

    pageNo:当前第几个

    pageSize:代表每一页展示多少条数据

    total:代表整个分页一共要展示多少条数据

    continues:代表分页连续页码个数

    举例:每一页3条数据 一共91条数据 【一共需要31页】

    分页器起始与结束数字计算 

    自定义分页器,在开发的时候先自己传递假的数据进行测试,调试成功以后在用服务器数据

    这里的数据是假的,将来用来替代的 

    来到分页器组件,动态拿到数据,通过计算属性,向下取整拿出数据渲染到页面上

    对于分页器而言,很重要的一个地方即为【算出:连续页面起始数字和结束数字】

    当前页面第8页

    6 7 8 9 10

    当前页面第20页

    18 19 20 21 22

    这个不正常的数字就是1 2 3 4

    正确情况 (这个页码不能写死)

    比如当前的是第8页,连续页码5

    6 7 8 9 10

    比如当前页面是8页 连续页码7

    5 6 7 8 9 10 11

     但是有bug,当前页如果为1,那么就有可能为负数

    假如:当前是1页

    1 2 3 4 5 而不是

    假如:当前是第2页

    1 2 3 4 5

    1. startNumAndEndNum(){
    2. const {continues,pageNo,totalPage}=this
    3. // 先定义俩个变量存储起始数字与结束数字
    4. let start=0,end=0
    5. // 不正常的现象【总页数没有连续页码多】
    6. if(this.continues>totalPage){
    7. start=1;
    8. end=this.totalPage
    9. }else{
    10. // 正常现象 连续页码为5,但总页码一定大于5
    11. // 起始数字
    12. start=pageNo-parseInt(continues/2)
    13. // 结束数字
    14. end=pageNo+parseInt(continues/2)
    15. // 不正常的数字【start数字出现0|负数】纠正
    16. if(start<1){
    17. start=1
    18. end=continues
    19. }
    20. // 把出现不正常的现象【end大于总页码】矫正
    21. if(end>totalPage){
    22. end=totalPage
    23. start=totalPage-continues+1
    24. }
    25. }
    26. }

    分页器动态展示

    分页器动态展示?分为上中下【中间部分】

     我们先测试一下

    这样写是没有问题的,但是如果我们传入的是第一页,又会发生错误

     完整代码是这样的,逻辑就是按照我们上次分析的

    1. <template>
    2. <div class="pagination">
    3. <h1>{{ startAndEnd }}</h1>
    4. <button @click="$emit('currentPage',pageNo - 1)" :disabled="pageNo==1">上一页</button>
    5. <button v-if="startAndEnd.start > 1" @click="$emit('currentPage',1)">1</button>
    6. <button v-if="startAndEnd.start > 2">.....</button>
    7. <!-- 中间连续页码的地方:v-for、数组、对象、数字、字符串 -->
    8. <button v-for="page in startAndEnd.end" :key="page" v-if="page >= startAndEnd.start" @click="$emit('currentPage',page)" :class="{active:pageNo==page}">{{ page }}</button>
    9. <button v-if="startAndEnd.end < totalPage - 1 ">......</button>
    10. <button v-if="startAndEnd.end < totalPage" @click="$emit('currentPage',totalPage)">{{ totalPage }}</button>
    11. <button @click="$emit('currentPage',pageNo + 1)" :disabled="pageNo==totalPage">下一页</button>
    12. <button style="margin-left: 30px">共 {{ total }} 条</button>
    13. </div>
    14. </template>
    15. <script>
    16. export default {
    17. name: "Pagination",
    18. props: ["total", "pageSize", "pageNo", "pagerCount"],
    19. computed: {
    20. //分页器一共多少页【总条数/每页展示条数】
    21. totalPage() {
    22. //向上取整数
    23. return Math.ceil(this.total / this.pageSize);
    24. },
    25. //底下的代码是整个分页器最重要的地方[算出连续五个数字、开头、结尾]
    26. startAndEnd() {
    27. //算出连续页码:开始与结束这两个数字
    28. let start = 0,
    29. end = 0;
    30. const { totalPage, pagerCount, pageNo } = this;
    31. //特殊情况:总共页数小于连续页码数
    32. if (totalPage < pagerCount) {
    33. start = 1;
    34. end = totalPage;
    35. } else {
    36. //正常情况:分页器总页数大于连续页码数
    37. start = pageNo - parseInt(pagerCount / 2);
    38. end = pageNo + parseInt(pagerCount / 2);
    39. //约束start|end在合理范围之内
    40. //约束头部
    41. if (start < 1) {
    42. start = 1;
    43. end = pagerCount;
    44. }
    45. //约束尾部
    46. if (end > totalPage) {
    47. end = totalPage;
    48. start = totalPage - pagerCount + 1;
    49. }
    50. }
    51. return { start, end };
    52. },
    53. },
    54. };
    55. </script>
    56. <style lang="less" scoped>
    57. .pagination {
    58. button {
    59. margin: 0 5px;
    60. background-color: #f4f4f5;
    61. color: #606266;
    62. outline: none;
    63. border-radius: 2px;
    64. padding: 0 4px;
    65. vertical-align: top;
    66. display: inline-block;
    67. font-size: 13px;
    68. min-width: 35.5px;
    69. height: 28px;
    70. line-height: 28px;
    71. cursor: pointer;
    72. box-sizing: border-box;
    73. text-align: center;
    74. border: 0;
    75. &[disabled] {
    76. color: #c0c4cc;
    77. cursor: not-allowed;
    78. }
    79. &.active {
    80. cursor: not-allowed;
    81. background-color: #409eff;
    82. color: #fff;
    83. }
    84. }
    85. }
    86. </style>

    分页器完成

    但是我们这样的数据是写死的,我们需要从服务器中拿数据,然后传进去

     这里的数据我们需要从state上来拿回数据。

    现在我们思考一个问题,那就是我们点击下一页,要从服务器捞数据。因此子传父,用自定义事件

      父组件自定义好了事件,让子组件绑定事件 

    :disabled="pageNo==1"这么写的原因是我们要考虑第一页和最后一页。因为我们点击第一页的上一页是没有效果的 。同时我们要把自己的页码值发送给父组件

    然后在整理数据

     

    1. getPageNo(pageNo){
    2. this.searchParams.pageNo=pageNo
    3. this.getData()
    4. }

    分页器添加类名

    就是点击谁就给谁类名 

    1. &.active {
    2. cursor: not-allowed;
    3. background-color: #409eff;
    4. color: #fff;
    5. }
  • 相关阅读:
    多巴胺自律上瘾
    小程序php好物优购毕业设计-附源码191755
    大数据存储ClickHouse
    freeswich学习
    1135 Is It A Red-Black Tree
    TypeScript 4.8 beta 发布:正在路上的装饰器、类型收窄增强、模板字符串类型中的 infer
    为什么Android 开发都在意Framework 底层知识?
    还在拿flex进行布局吗?快来试试grid网格布局吧
    华为---DHCP中继代理简介及示例配置
    vue的使用及绑定和一些vue指令
  • 原文地址:https://blog.csdn.net/weixin_64612659/article/details/130793203