用Vue写一个分页器的示例代码


Posted in Javascript onApril 22, 2018

之前一直想要自己试着实现一个分页器,但是一直拖,今天写完,大概照着网易云音乐的样子来完成。这个小例子很简单,通过这个小例子,可以学习到Vue计算属性的使用,并了解到写分页器需要区分的情况。这篇文章会慢慢从头来实现这个小例子,相信你一定会学会,而且看完了我的思路之后说不定会有更棒的思路和想法!

实现的效果是这样子的:

用Vue写一个分页器的示例代码

一、先简单布局

<template>
 <div class="pageContainer">
  <ul class="pagesInner">
   <li class="page"><span class="fa fa-chevron-left" aria-hidden="true"></span></li>
   <li class="page" v-for="(item, index) in pages" :key="index">
    <span>{{item}}</span>
   </li>
   <li class="page"><span class="fa fa-chevron-right" aria-hidden="true"></span></li>
  </ul>
 </div>
</template>

<script>
export default {
 computed: {
  pages() {
   return 10;
  }
 }
};
</script>

效果如下:

用Vue写一个分页器的示例代码

有两个地方说下:

  1. 最前面和最后面两个icon用的font awesome的cdn
  2. 使用v-for来进行渲染的数据用的是计算属性里的pages,暂时写了一个数据11,所以渲染出了11个标签

二、理清思路,在这个例子里最重要

这篇文章的例子是参照了网易云音乐里的分页方法,网易的图:

用Vue写一个分页器的示例代码

它有几个特点:

  1. 首页和尾页一直都有
  2. 最多时候有11个标签页,包括两个 ... ,但是它们不能点击,所以我也把例子里的页码设为11
  3. 在当前页变动的时候,页码的形态也会发生变化,总共有三种情况,这个下面会细说

分页的三种情况:

第一种:当前页码小于等于5的时候

如图:

用Vue写一个分页器的示例代码

这种情况首页尾页保留,倒数第二个页面为..., 页码从头往后算

第二种情况:当前页码处于最后5个的时候

如图:

用Vue写一个分页器的示例代码

首页和尾页依然保留,第二个页码为...,页码从最后向前算

第三种情况:页面处于较中间位置的时候

如图:

用Vue写一个分页器的示例代码

首页和尾页都保留,第二个页码和倒数第二个页码都为 ... ,同时页面从当前页码位置向两侧算

三、用代码来实现上面的三种情况

从上面的思路来看,页码具体如何呈现由当前页码的位置决定,所以我们要在data里设置一个currentPage:1,而计算属性里用于渲染页码的pages通过currentPage来控制,同时还需要一个总页数totalPages:50。

先写第一种情况:

<script>
export default {
 data() {
  return {
   currentPage: 1,
   totalPages: 50
  }
 },
 computed: {
  pages() {
   const c = this.currentPage
   const t = this.totalPages
   if (c <= 5) {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, '...', t]
   }
  }
 }
};
</script>

效果如下:

用Vue写一个分页器的示例代码

写第二种情况,再加个if:

<script>
export default {
 data() {
  return {
   currentPage: 47,
   totalPages: 50
  }
 },
 computed: {
  pages() {
   const c = this.currentPage
   const t = this.totalPages
   if (c <= 5) {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, '...', t]
   } else if (c >= t - 4) {
    return [1, '...', t-8, t-7, t-6, t-5, t-4, t-3, t-2, t-1, t]
   }
  }
 }
};
</script>

把currentPage的值设为>= 46,效果如下:

用Vue写一个分页器的示例代码

把第三种情况加上:

computed: {
  pages() {
   const c = this.currentPage
   const t = this.totalPages
   if (c <= 5) {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, '...', t] //第一种情况
   } else if (c >= t - 4) {
    return [1, '...', t-8, t-7, t-6, t-5, t-4, t-3, t-2, t-1, t] //第二种情况
   } else {
    return [1, '...', c-3, c-2, c-1, c, c+1, c+2, c+3, '...', t] //第三种情况
   }
  }
 }

基本就是这样,已经可以通过改变currentPage的值查看分页器的变化了。

接下来实现点击相应的页码来改变currentPage的值,只要写一个点击事件再写一个函数就好了。

<li class="page" 
  v-for="(item, index) in pages" 
  :key="index"
  :class="{actived: item === currentPage}"  // 给点击到的当前页码添加样式
  @click="select(item)"   // 添加一个点击事件
>

...

methods: {
  select(item) {
    this.currentPage = item
  }
}

...

actived: {
  border-color: #2d8cf0;
  background-color: #2d8cf0;
  color: #fff;
}

效果如下:

用Vue写一个分页器的示例代码

为了让当前页码更清楚,再在页面上加上当前多少页

<div>当前第{{currentPage}}页</div>

效果如下:

用Vue写一个分页器的示例代码

发现了一bug,就是我们每次点击的时候,都是将item的具体内容传递过去改变currentIPage的,但是当我们点的 ... 的时候就把它也传递过去了,但是它不是我们要的页码的数据,在计算的时候就出错了,所以我们需要做一点处理。同时,还有再点击当前页码的时候也不必再执行select函数了。

简单改写一下select函数:

select(n) {
  if (n === this.currentPage) return 
  if (typeof n === 'string') return 
  this.currentPage = n
}

这样就正常了。

再把两侧icon向前一页和向后一页的功能加上,因为一个是加1一个是减1,所以写一个函数传递不同的参数就行了。

<li class="page" @click="prevOrNext(-1)"><span class="fa fa-chevron-left" aria-hidden="true"></span></li>

...

<li class="page" @click="prevOrNext(1)"><span class="fa fa-chevron-right" aria-hidden="true"></span></li>

...

prevOrNext(n) {
  this.currentPage += n
}

效果如下:

用Vue写一个分页器的示例代码

呃,边界问题,当currentPage为1时就不能再减了,当它为最大时也不能再加了。

改写一下代码:

prevOrNext (n) {
 this.currentPage += n
 this.currentPage < 1
 ? this.currentPage = 1
 : this.currentPage > this.totalPages
  ? this.currentPage = this.totalPages
  : null
}

这下就可以了,如图:

用Vue写一个分页器的示例代码

四、 结语

写到这里,这个分页器基本功能就写完了,当然,我们还可以继续封装,在每次改变currentPage的时候用this.$emit通知外面实现通信,还可以通过props来向内传递数据,比如传递totalPages等,这些都是可以继续完善的内容。最重要的一点,关于分页器的具体计算方法,我用的是最笨的方法,所以同志们要是知道更好的办法记得留言啊~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 模拟坦克大战游戏(html5版)附源码下载
Apr 08 Javascript
JavaScript link方法入门实例(给字符串加上超链接)
Oct 17 Javascript
javascript相关事件的几个概念
May 21 Javascript
js数组常见操作及数组与字符串相互转化实例详解
Nov 10 Javascript
基于AngularJS前端云组件最佳实践
Oct 20 Javascript
ES6正则表达式的一些新功能总结
May 09 Javascript
Vue2.0如何发布项目实战
Jul 27 Javascript
初学者AngularJS的环境搭建过程
Oct 27 Javascript
用最少的JS代码写出贪吃蛇游戏
Jan 12 Javascript
Vue循环组件加validate多表单验证的实例
Sep 18 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
Apr 28 jQuery
在vue中使用image-webpack-loader实例
Nov 12 Javascript
vue-cli3.0 特性解读
Apr 22 #Javascript
JS实现的哈夫曼编码示例【原始版与修改版】
Apr 22 #Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
Apr 22 #Javascript
Vue下滚动到页面底部无限加载数据的示例代码
Apr 22 #Javascript
关于Angularjs中自定义指令一些有价值的细节和技巧小结
Apr 22 #Javascript
jQuery中图片展示插件highslide.js的简单dom
Apr 22 #jQuery
手写简单的jQuery雪花飘落效果实例
Apr 22 #jQuery
You might like
风味层面去分析咖啡油脂
2021/03/03 咖啡文化
通过修改referer下载文件的方法
2008/05/11 Javascript
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
一个XML格式数据转换为图表的例子
2010/02/09 Javascript
Tinymce+jQuery.Validation使用产生的BUG
2010/03/29 Javascript
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
JavaScript中的定时器之Item23的合理使用
2015/10/30 Javascript
javascript实现保留两位小数的多种方法
2015/12/18 Javascript
JQuery 的跨域方法推荐_可跨任何网站
2016/05/18 Javascript
深入理解Angularjs中的$resource服务
2016/12/31 Javascript
vue axios基于常见业务场景的二次封装的实现
2018/09/21 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
简述vue路由打开一个新的窗口的方法
2018/11/29 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
2019/07/13 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
原生js实现购物车功能
2020/09/23 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
2020/11/17 Vue.js
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
用Python的urllib库提交WEB表单
2009/02/24 Python
python 切片和range()用法说明
2013/03/24 Python
深入理解Python中各种方法的运作原理
2015/06/15 Python
利用aardio给python编写图形界面
2017/08/21 Python
基于Python的文件类型和字符串详解
2017/12/21 Python
python3图片文件批量重命名处理
2019/10/31 Python
python框架django项目部署相关知识详解
2019/11/04 Python
详解window.open被浏览器拦截的解决方案
2019/07/18 HTML / CSS
采用专利算法搜索最廉价的机票:CheapAir
2016/09/10 全球购物
欧洲品牌瓷器餐具网上商店:Porzellantreff.de
2018/04/04 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
Linux内核产生并发的原因
2012/07/13 面试题
房地产销售员的自我评价分享
2013/12/04 职场文书
长辈证婚人证婚词
2014/01/09 职场文书
结婚保证书范文
2014/04/29 职场文书
未受刑事制裁公证证明
2014/09/20 职场文书
校园新闻广播稿5篇
2014/10/10 职场文书
看古人们是如何赞美老师的?
2019/07/08 职场文书