avatar

麦兜的小站

MDO.INK

  • 首页
  • 随笔
  • 知识库
  • 归档
  • 动态
  • 标签
  • 关于
Home 一个漂亮的Vue分页器组件的实现
文章

一个漂亮的Vue分页器组件的实现

Posted 2025-02-1 Updated 2025-02- 1
By power 已删除用户
23~30 min read

思路:基于连续页码进行判断

  • 需要添加分页器的组件(Search组件)中
 <!-- 分页器 -->
          <Pagination
            :pageNo="searchParams.pageNo"
            :pageSize="searchParams.pageSize"
            :total="total"
            :continues="5"
            @getPageNo="getPageNo"
          />
  1. 在分页器组件上传递【当前页码pageNo】、【每页展示的数据pageSize】、【总的数据total】、【连续的页码(重要)】 ,定义一个【自定义事件getPageNo】把用户点击的【当前页码pageNo】传递回来,并进行数据请求
  2. methods中定义函数接受分页器传回来的【当前页pageNo】

  1. 分页器,分成三部分 ------【如下图】

  • 分页器组件(Pagination)中
 1、通过props取得 Search组件传递的参数
 props: ["pageNo", "pageSize", "total", "continues"],
 2、**在分页器组件计算属性computed中计算总共多少页/最后一页 - this.total / this.pageSize**

【记得向上取整Math.ceil(),例:当总的数据total=30,每页的数据pageSize=3,那么10页刚刚好展示完毕,如果每页的数据pageSize=4,有7页展示4条数据,还有2条需要下一页展示,所以进行取整,Math.ceil(30/4)=8】

 3、**在分页器组件计算属性computed中计算连续页码【至少5页】的起始数字start、结束数字end【当前页pageNo在连续页码中】**
  • 情况判断一:连续的页码 > 总的页数 【start=1,end=总的页数】
  • 情况判断二:连续的页码 < 总的页数 【计算 start = pageNo - parseInt(continues / 2)、end = pageNo + parseInt(continues / 2);】
    • 分情况一:start数字出现0 | 负数 【continues=5,pageNo=1、2的时候】
    • 分情况二:end数字大于总页码 【continues=5,totalPage=30,pageNo=29、30的时候】
  • 记得:最后把 start、end返回

  • 上下一页 、第一页、最后一页的判断
- 上一页:如果当前页pageNo=1,就不显示上一页按钮,绑定点击事件,点击触发getPageNo自定义事件,把当前页pageNo-1当参数传递回search组件,请求上一页的数据
- 第一页:如果连续页码的起始数字start>1,就显示前面定义好的第一页;小于的话,显示连续页码中的第一页按钮。点击事件同上,由于可能处理选中状态,所以绑定一个类【已经在css中定义好的】,添加选中颜色,当然需要判断是否是选中的页
- 省略...小点:当连续页码的start=3时,显示,也就表示,他们之间还有一页
- 连续页码:通过v-for遍历数字,遍历连续页码中end,并判断其中的元素page>start,才显示【因为传过来的连续页码为5,所以在分页器中连续页码出现最大的就是end-start=5,去掉start之前的页码,才能使连续页码为5】,其他同上
- 省略...小点 | 最后一页 | 下一页:计算同上【totalPage是上面已经算完的总页数|最后一页】

  • 静态组件
<template>
  <div class="pagination">
    <button>1</button>
    <button>上一页</button>
    <button>···</button>

    <button>3</button>
    <button>4</button>
    <button>5</button>
    <button>6</button>
    <button>7</button>

    <button>···</button>
    <button>9</button>
    <button>上一页</button>

    <button style="margin-left: 30px">共 60 条</button>
  </div>
</template>

<script>
  export default {
    name: "Pagination",
  }
</script>

<style lang="less" scoped>
  .pagination {
    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;
      }
    }
  }
</style>

1、 注册组件

注意:一般使用分页器组件的地方有很多,所以我把他注册为了全局组件

  • 在vue脚手架的main.js中配置

2、挂载组件

  • 挂载并传参

【当前页码pageNo】、【每页展示的数据pageSize】、【总的数据total】、【连续的页码(重要)】 ,定义一个【自定义事件getPageNo】把用户点击的【当前页码pageNo】传递回来,并进行数据请求

  • 自定义事件接受参数当前页,再次发请求【根据你自己的来】

3、分页器组件代码

<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
      @click="$emit('getPageNo', pageNo + 1)"
      :disabled="pageNo == totalPage"
    >
      下一页
    </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);
    },


    startNumAndEndNum() {
      const { continues, pageNo, totalPage } = this; 

      let start = 0,
        end = 0;

      if (continues > totalPage) {
        start = 1;
        end = totalPage;
      } else {

        start = pageNo - parseInt(continues / 2);
        end = pageNo + parseInt(continues / 2);

        if (start < 1) {
          start = 1;
          end = continues;
        }

        if (end > totalPage) {
          start = totalPage - continues + 1;
          end = totalPage;
        }
      }
      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;
    }
  }
}
</style>
前端
License:  CC BY 4.0
Share

Further Reading

Jun 25, 2025

Vue实现顶部导航跟随页面联动效果

需求背景 最近也是应我一位同学的要求,给他的公司制作一个官网,那也就是拾起了一些基础的知识,搜索了一些其它的文章有实现这种效果的,但大多导航都是在侧边,然后点击导航对应的部分内容滑到最上面,跟我这次设...

Jun 20, 2025

Share.js - 一键分享到微博、QQ空间、QQ好友、微信、腾讯微博、豆瓣、Facebook、Twitter、Linkedin、Google+、点点

一键分享到微博、QQ空间、QQ好友、微信、腾讯微博、豆瓣、Facebook、Twitter、Linkedin、Google+、点点等社交网站,使用字体图标。 有两种安装方式: 使用npm npmi...

Jun 19, 2025

node express实现热更新

在使用node进行开发的时候,每次修改文件,都需要重启express服务很麻烦 我们可以使用nodemon这个库,修改文件后可以自动重启express服务。 安装: npminstall--save-...

OLDER

vue路由传参方式的几种方式与获取参数

NEWER

适用于Vue 3的最佳开源分页库

Recently Updated

  • 如何实现接口幂等性
  • 10个npm工具包
  • How to set up PHP7.4 on MacOS.
  • Automa:一键自动化,网页数据采集与工作流程优化专家Automa:解锁自动化
  • Mac 下用 brew 搭建 LNMP

Trending Tags

thinkphp clippings

Contents

©2025 麦兜的小站. Some rights reserved.

Using the Halo theme Chirpy