分页是项目中常会用到的,网上的插件也很多,但是有些功能太齐全反而不是必要的,所以抽时间自己写了一下(小白写代码,若发现问题还请及时赐教,感激不尽……)

如图,想要一个这样的页码:

  a. 上一页、下一页固定展示

  b. 第一页、最后一页固定展示

  c. 中间,即:左右...之间需要展示的页码个数可自定义

  d. 可任意选择页面展示数据条数

一、不需要展示 ,只展示页码,需要定义3个变量:pageNum(当前页码)、totalNum(总页码)、middleSize(中间,即左右...之间需要展示的页码 个数)

  1、totalNum <= middleSize+2时,只显示1,2,3,4没有...,(为什么是totalNum <= middleSize+2,而不是totalNum <= middleSize,这是因为第一个、最后一页是固定展示的),totalNum=7,middleSize=5,展示情况如下图:

  2、pageNum <= middleSize时,右侧...显示,totalNum=8,middleSize=5,展示情况如下图:

  3、pageNum >= totalNum - ( middleSize - 1 )时,左侧...显示,totalNum=100, middleSize=5,展示情况如下图:

  4、除以上3种情况,左右两侧...都展示,那中间页码如何展示,代码如下:

// ④ 展示左右两侧的'...'
let pages = [1, '...'];
// 当左右两侧的...都展示时,中间的页码该如何展示呢?其实就是 当前页码 - (中间要展示页码的个数/2向下取整) 到 当前页码 + (中间要展示页码的个数/2向下取整)即可
const half = Math.floor(this.middleSize/2); // 向下取整
for(let i=this.pageNum-half; i<=this.pageNum+half; i++) {
pages.push(i);
}
pages.push('...');
pages.push(this.totalNum);
return pages;

二、左侧页面展示条数代码实现较简单,可查看全部代码:

 <template>
<div class="pageContainer">
<!-- 当前页面展示多少条数据 -->
<div class="pageSizeInner">
<div class="totalCount">共 {{totalCount}} 条</div>
<div class="pageSize">
<select v-model="perPageCount" @change="changePerPageCount">
<option :value="item" v-for="(item, index) in page_size" :key="index">{{item}}</option>
</select>
</div>
</div> <!-- 页码部分 -->
<ul class="pagesInner">
<!-- 上一页 -->
<li class="page" :class="{noClick : pageNum == 1}" @click="preOrNext(-1)">
<span>上一页</span>
</li>
<!-- 页码 -->
<li class="page" :class="{actived : item === pageNum}" v-for="(item, index) in displayPages" :key="index" @click="select(item)">
<span>{{item}}</span>
</li>
<!-- 下一页 -->
<li class="page" :class="{noClick : pageNum == totalNum}" @click="preOrNext(1)">
<span>下一页</span>
</li>
</ul>
</div>
</template> <script>
export default {
data() {
return {
totalCount: 9999, // 总共多少条数据
page_size: ['100条/页', '200条/页', '300条/页', '400条/页'], // 每页展示多少条数据
pageNum: 1, // 当前页码
totalNum: 20, // 总页码
middleSize: 5, // 中间显示几个页码
perPageCount: 0, // 每页展示多少条数据
}
},
computed: {
// 展示页码
displayPages() {
// ① 只展示'上一页'、'页码'、'下一页'
if(this.totalNum <= this.middleSize + 2) {
let pages = [];
for(let i=1; i<=this.totalNum; i++) {
pages.push(i);
}
return pages;
}else if(this.pageNum <= this.middleSize) { // this.pageNum <= this.middleSize+2
// ② 只展示右侧'...',只要当前页码小于或者等于要展示的中间页码时就展示
let pages = [1];
for(let i=2; i<this.middleSize+1; i++) {
pages.push(i);
}
pages.push('...');
pages.push(this.totalNum);
return pages;
}else if(this.pageNum >= this.totalNum - (this.middleSize - 1)) {
// ③ 只展示左侧'...',主要当前页码 大于或等于 总页码-(中间要展示页码的个数 - 1)就展示
let pages = [1, '...'];
for(let i=this.totalNum-this.middleSize+1; i<=this.totalNum; i++) {
pages.push(i);
}
return pages;
}else {
// ④ 展示左右两侧的'...'
let pages = [1, '...'];
// 当左右两侧的...都展示时,中间的页码该如何展示呢?其实就是 当前页码 - (中间要展示页码的个数/2向下取整) 到 当前页码 + (中间要展示页码的个数/2向下取整)即可
const half = Math.floor(this.middleSize/2); // 向下取整
for(let i=this.pageNum-half; i<=this.pageNum+half; i++) {
pages.push(i);
}
pages.push('...');
pages.push(this.totalNum);
return pages;
}
}
},
mounted() {
// 每页展示多少条数据
this.perPageCount = this.page_size[0];
// 计算总页码是多少
this.totalNum = Math.ceil(this.totalCount/parseInt(this.perPageCount));
},
methods: {
// 点击'上一页'、'下一页'
preOrNext(n) {
this.pageNum = this.pageNum + n;
this.pageNum <= 1 ? this.pageNum = 1 : this.pageNum > this.totalNum ? this.pageNum = this.totalNum : null;
// 作为子组件,当前页码发生改变时需要通知父组件
// this.$emit('pageNumChanged', this.pageNum);
},
// 点击'页码'
select(item) {
if(typeof item === 'string') return;
if(item == this.pageNum) return;
this.pageNum = item;
// 作为子组件,当前页码发生改变时需要通知父组件
// this.$emit('pageNumChanged', this.pageNum);
},
// 选择页面展示条数,重新计算总页码
changePerPageCount() {
this.totalNum = Math.ceil(this.totalCount/parseInt(this.perPageCount));
}
}
}
</script> <style lang="scss" type="text/css">
.pageContainer {
display: flex;
justify-content: space-between;
.pageSizeInner {
padding-top: 9px;
.totalCount {
display: inline-block;
margin-right: 5px;
}
.pageSize {
display: inline-block;
>select {
padding: 0 3px;
width: 100px;
height: 30px;
font-size: 12px;
border: 1px solid #eee;
border-radius: 2px;
box-sizing: border-box;
outline: none;
}
}
}
.pagesInner {
display: inline-block;
text-align: center;
font-size: 0;
li {
display: inline-block;
margin: 5px;
list-style: none;
>span {
display: block;
width: 46px;
height: 36px;
line-height: 36px;
text-align: center;
font-size: 12px;
border: 1px solid #eee;
border-radius: 5px;
cursor: pointer;
}
&.noClick {
>span {
cursor: no-drop;
// border-color: transparent;
}
}
&.actived {
>span {
border-color: #2d8cf0;
background-color: #2d8cf0;
color: #fff;
}
}
}
}
}
</style>

(注:记住一个原则就可实现分页,右点左侧页码个数 = middleSize, 左点右侧页码个数 = middleSize,totalNum<=middleSize+2无点只有页码,除以上三种情况外左右两侧...都展示)

用vue写一个分页器代码的更多相关文章

  1. 用ES6的class模仿Vue写一个双向绑定

    原文地址:用ES6的class模仿Vue写一个双向绑定 点击在线尝试一下 最终效果如下: 构造器(constructor) 构造一个TinyVue对象,包含基本的el,data,methods cla ...

  2. 用vue写一个仿简书的轮播图

    原文地址:用vue写一个仿简书的轮播图 先展示最终效果: Vue的理念是以数据驱动视图,所以拒绝通过改变元素的margin-top来实现滚动效果.写好css样式,只需改变每张图片的class即可实现轮 ...

  3. 用vue写一个仿app下拉刷新的组件

    如果你用vue弄移动端的页面,那么下拉刷新还是比较常见的场景,下面来研究如何写一个下拉刷新的组件(先上图); 由于节省大家的时间,样式就不贴出来了. html结构也不必介绍了,直接看代码吧-.- &l ...

  4. 使用Vue写一个九九乘法表

    Vue.js是一套构建用户界面的渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计. 下面是在Vue 测试实例 - 菜鸟教程(runoob.com)使用Vue写的一个九九乘法表, ...

  5. [Vue]写一个简单的文件上传控件

    ​这篇将介绍如何写一个简单的基于Vue+Element的文件上传控件. 控件将具有 1. 上传队列的列表,显示文件名称,大小等信息,可以显示上传进度实时刷新 2. 取消上传 ​ 使用Element的u ...

  6. 教你用Vue写一个开心消消乐

    之前做过一个算法题,算法要求就是写一个开心消消乐的逻辑算法,当时也是考虑了一段时间才做出来.后来想了想,既然核心算法都有了,能不能实现一个开心消消乐的小游戏呢,于是花了两天时间做了一个小游戏出来. 效 ...

  7. Vue学习—Vue写一个图片轮播组件

    1.先看效果: 熟悉的图片轮播,只要是个网站,百分之90以上会有个图片轮播.我认为使用图片轮播. 第一可以给人以一种美观的感受,而不会显得网站那么呆板, 第二可以增加显示内容,同样的区域可以显示更多内 ...

  8. 使用Vue写一个登陆页面并在管理页面查看和修改

    注册页面代码如下html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  9. vue 写一个炫酷的轮播图

    效果如上图: 原理: 1.利用css 的 transform 和一些其他的属性,先选五张将图片位置拍列好,剩余的隐藏 2.利用 js 动态切换类名,达到切换效果 css代码如下 .swiper-cer ...

随机推荐

  1. LC 377. Combination Sum IV

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  2. Oracle登录认证

    oracle 登录认证 Table of Contents 1. 简介 2. authentication_services 2.1. 不同登录方式的写法 3. sysdba角色登录认证 3.1. 无 ...

  3. URL编码和解码

    1. 为什么需要编码 当数据不利于处理.存储的时候,就需要对它们进行编码.如对字符进行编码是因为自然语言中的字符不利于计算机处理和存储.对图片信息.视频信息.声音信息进行压缩.优化,将其“格式化”,是 ...

  4. 执行scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysqldb命令时一直报错:

    Can't locate Data/Dumper.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /u ...

  5. delphi treeview的子节点图标?

    代码实现不同的子节点图标效果. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  6. 利用Oracle定时任务重置序列

    业务需求是:二元化编号规则:RYH+年月+001(开始),按月计算,每月1号重置为001 数据库中已有序列和函数如下: 解决方法:采用Oracle定时任务,每月1号重置该序列从1开始增长,SQL如下: ...

  7. React Native细节知识点总结<二>

    1.关于React Native导出组件的export default和export的问题: 一个文件只能有一个export default,可以有多个export export class Temp ...

  8. java中,有关移位运算符的有关讨论

    java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     右移运算符,num >& ...

  9. 实战keras——用CNN实现cifar10图像分类

    原文:https://blog.csdn.net/zzulp/article/details/76358694 import keras from keras.datasets import cifa ...

  10. .Netcore 2.0 Ocelot Api网关教程(3)- 路由聚合

    在实际的应用当中,经常会遇到同一个操作要请求多个api来执行.这里先假设一个应用场景:通过姓名获取一个人的个人信息(性别.年龄),而获取每种个人信息都要调用不同的api,难道要依次调用吗?在Ocelo ...