一个可复用的vue分页组件


Posted in Javascript onMay 15, 2017

不废话,先上组件文件pages.vue:

<template>
 <div class="pages-box" v-if="pageTotal > 0">
  <ul class="pages">
   <li class="pages-prev">
    <a v-if="pageNow != 1" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="prevClick">上一页</a>
   </li>
   <!--如果只有一页就不显示固定的第一个分页按钮了,避免重复-->
   <template v-if="pageTotal > 1">
    <li v-for="i in pageBegin" class="pages-li" :class="{active:i == pageNow}">
     <span v-if="i == pageNow" v-text="i"></span>
     <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
    </li>
   </template>
   <li v-if="ellipsis[0] > slider">
    <span>...</span>
   </li>
   <li v-for="i in pageMiddle" class="pages-li" :class="{active:i == pageNow}">
    <span v-if="i == pageNow" v-text="i"></span>
    <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
   </li>
   <li v-if="pageTotal - ellipsis[1] > slider">
    <span>...</span>
   </li>
   <li v-for="i in pageEnd" class="pages-li" :class="{active:i == pageNow}">
    <span v-if="i == pageNow" v-text="i"></span>
    <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
   </li>

   <li class="pages-next">
    <a v-if="pageNow != pageTotal" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="nextClick">下一页</a>
   </li>
  </ul>
 </div>
</template>

<script>
 export default{
  name: 'pages',
  props: {
   //总页数
   total: {
    type: [Number, String],
    required: true
   },
   //当前页
   now: {
    type: [Number, String],
    default: 1
   }
  },
  data() {
   return {
    //当前页
    pageNow: this.now,
    //总页数
    pageTotal: this.total,
    //输入的页码
    pageNum: "",
    //显示分页按钮的个数
    length: 8,
    //前后固定的分页按钮个数
    slider: 1
   }
  },
  watch: {
   total(val){
    let page_total = parseInt(val);
    page_total = (isNaN(page_total) || page_total < 1) ? 1 : page_total;
    this.pageTotal = page_total;
   },
   now(val){
    let page_now = parseInt(val);
    page_now = (isNaN(page_now) || this.pageTotal < 2 || page_now < 1) ? 1 : page_now;
    page_now = page_now > this.pageTotal ? this.pageTotal : page_now;
    this.pageNow = page_now;
   }
  },
  computed: {
   //前边显示固定分页数
   pageBegin(){
    return Math.min(this.slider, this.ellipsis[0]);
   },
   //中间显示分页数
   pageMiddle(){
    let arr = [];
    for (let i = this.ellipsis[0] + 1; i <= this.ellipsis[1]; i++) {
     arr.push(i);
    }
    return arr;
   },
   //后边显示分页数
   pageEnd(){
    let arr = [];
    for (let i = this.ellipsis[2] + 1; i <= this.pageTotal; i++) {
     arr.push(i);
    }
    return arr;
   },
   /**
    * 出现三个点时的分页的范围
    * @returns {*[]}
    * begin: 开始页码
    * end: 结束页码
    * end_max: 结束页码的最大值
    */
   ellipsis() {
    let end_max = this.pageTotal - this.slider;
    let begin = this.pageNow - (this.length / 2) + this.slider;
    begin = begin < 1 ? 1 : begin;
    let end = begin + this.length - 2 * this.slider;
    //当begin达到最小值后需要根据begin重新计算end以保证显示的分页按钮个数不变
    end = begin < this.slider ? (end + this.slider - begin) : end;
    if (end >= end_max) {
     end = end_max;
     //当end达到最大值后需要根据end重新计算begin以保证显示的分页按钮个数不变
     begin = (end - this.length + 2 * this.slider) < 1 ? 1 : (end - this.length + 2 * this.slider);
    }
    return [begin, end, end_max];
   }
  },
  methods: {
   //上一页
   prevClick() {
    this.pageNow--;
    this.pageNow = this.pageNow < 1 ? 1 : this.pageNow;
    this.changePage(this.pageNow);
   },
   //下一页
   nextClick() {
    this.pageNow++;
    this.pageNow = this.pageNow > this.pageTotal ? this.pageTotal : this.pageNow;
    this.changePage(this.pageNow);
   },
   //点击页码
   pageClick(e) {
    this.pageNow = Number(e.target.innerText.trim());
    this.changePage(this.pageNow);
   },
   //输入页码
   pageInput(e){
    let num = parseInt(e.target.innerText);
    if(isNaN(num)){
     this.pageNum = '';
     e.target.innerText = '';
    } else {
     this.pageNum = num;
     //e.target.innerText = num;
    }
   },
   //跳转到输入的页码
   goClick() {
    this.pageNum = this.pageNum < 1 ? 1 : this.pageNum;
    this.pageNum = this.pageNum > this.pageTotal ? this.pageTotal : this.pageNum;
    this.pageNow = this.pageNum;
    this.pageNum = "";
    this.changePage(this.pageNow);
   },
   // 切换分页
   changePage(page){
    let {name, params, query} = this.$route;
    this.$router.push({
     name,
     params: Object.assign(params, {page}),
     query
    });
   }
  }
 }
</script>
<style lang="sass" type="text/scss" rel="stylesheet/scss">
 @import '../scss/base/variables';

 .pages-box{
  position: relative;
  padding: 5px 10px;
  margin: 20px 0;
  text-align: center;
 }

 .pages{
  display: inline-block;
  padding: 10px 0;
  &:after{
   content: "";
   display: table;
   line-height: 0;
   clear: both;
  }
  li{
   float: left;
   height: 20px;
   line-height: 20px;
   text-align: center;
   margin: 0 2px;
   box-sizing: border-box;
   font-size: 13px;
   span, a{
    display: block;
    width: 100%;
    height: 100%;
    padding: 0 2px;
    box-sizing: border-box;
   }
  }
  .pages-li{
   min-width: 30px;
   border: 1px solid $theme;
   color: $theme;
   a{
    color: $theme;
   }
   &.active{
    span{
     background: $theme;
     color: #fff;
    }
   }
  }
  .pages-prev, .pages-next{
   padding: 0 8px;
   font-size: 12px;
   a{
    display: block;
    height: 100%;
    position: relative;
    color: $theme;
    &:before{
     content: '';
     position: absolute;
     top: 50%;
     display: block;
     width: 6px;
     height: 6px;margin-top:-4px;
     border-left: 1px solid $theme;
     border-top: 1px solid $theme;
    }
   }
  }
  .pages-prev a{
   padding-left: 8px;
   &:before{
    transform:rotate(-45deg);
    left: 0;
   }
  }
  .pages-next a{
   padding-right: 8px;
   &:before{
    transform:rotate(135deg);
    right: 0;
   }
  }
  .pages-num{
   .num-input{
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    line-height: 20px;
    border-radius: 2px;
    border: 1px solid $theme;
    color: $theme;
    text-align: center;
    outline: none;
   }
  }
  .pages-go{
   a{
    color: $theme;
   }
   span{
    color: #666;
   }
  }
 }
</style>

使用方法:

在需要分页的地方使用分页组件标签,比如这里的order.vue:

<!--分页组件-->
<pages :now="page" :total="totalPage" v-if="totalPage > 0"></pages>

在data中设置当前页和总页面的默认值

data(){
    return {
      totalPage:1,
      page:1,
        }
    },

考虑一下我们希望我们点击页数按钮后发生什么

首先,点击某页数时路由会改变页数,从路由获取当前页

this.page = this.$route.params.page;

接着,我们希望有一个getorderfromServer方法将当前页数发送给服务器,再将返回的数据更新在页面上

getorderfromServer({
          currentPage:this.page
        })

最后调用的方法:

methods: {
      // 查询全部订单
      getorderfromServer(){
        this.loading = true;
        this.page = this.$route.params.page;
        getorderfromServer({
          currentPage: this.page,
          orderTimeStart:this.orderTimeStart,
          orderTimeEnd:this.orderTimeEnd,
          serviceName:this.serviceName,
          shopName:this.shopName,
          status: this.status
        }).then(({code, data}) => {
          if (code == 200) {
            this.Orderlist = data.list;
            this.totalPage = data.totalPage;
          }
          this.loading = false;
        }).catch(err => {
          this.tip('服务内部错误', 'error');
          this.Orderlist = {};
          this.loading = false;
        });
      },
    }

注意通过路由对方法作出响应,每次路由改变都调用此方法以更新页面

watch: {
      $route: 'getorderfromServer'
    }

还要对路由信息进行改造,让每一页(尤其是第一页)都有路由页数信息,可以对第一页进行重定向以达到目的:

{
  path: 'order',
  redirect: 'order/page/1',
},
{
  path: 'order/page/:page',
  component(resolve){
    require.ensure([], function (require) {
      resolve(require('../modules/personal/order/myorder.vue'));
    }, 'modules/personal')
  },
  name:'order',
  meta: {
    login: 'none'
  }
},

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

Javascript 相关文章推荐
Javascript解决常见浏览器兼容问题的12种方法
Jan 04 Javascript
javascript中如何处理引号编码&amp;#034;
Aug 15 Javascript
基于jQuery实现下拉框
Nov 24 Javascript
angularJS提交表单(form)
Feb 09 Javascript
JS实现的数组全排列输出算法
Mar 19 Javascript
javascript中eval和with用法实例总结
Nov 30 Javascript
js实现随机抽选效果、随机抽选红色球效果
Jan 13 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
Feb 27 Javascript
easyUI下拉列表点击事件使用方法
May 18 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
使用socket.io实现简单聊天室案例
Jan 02 Javascript
vue父子组件的通信方法(实例详解)
Nov 10 Javascript
jQuery操作css样式
May 15 #jQuery
Node.JS文件系统解析实例详解
May 15 #Javascript
使用Browserify来实现CommonJS的浏览器加载方法
May 14 #Javascript
js实现股票实时刷新数据案例
May 14 #Javascript
Ext JS 实现建议词模糊动态搜索功能
May 13 #Javascript
js,jq,css多方面实现简易下拉菜单功能
May 13 #Javascript
easyui combogrid实现本地模糊搜索过滤多列
May 13 #Javascript
You might like
dedecms中常见问题修改方法总结
2007/03/21 PHP
PHP Warning: Module 'modulename' already loaded in问题解决办法
2015/03/16 PHP
PHP 数组基本操作小结(推荐)
2016/06/13 PHP
二级域名转向类
2006/11/09 Javascript
表单提交时自动复制内容到剪贴板的js代码
2007/03/16 Javascript
js对数字的格式化使用说明
2011/01/12 Javascript
超轻量级的基于jquery的三级展开列表
2011/04/26 Javascript
使用原生javascript创建通用表单验证——更锋利的使用dom对象
2011/09/13 Javascript
js 获取(接收)地址栏参数值的方法
2013/04/01 Javascript
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
关于javascript模块加载技术的一些思考
2014/11/28 Javascript
Node.js实现的简易网页抓取功能示例
2014/12/05 Javascript
第一次接触神奇的Bootstrap基础排版
2016/07/26 Javascript
js中的eval()函数把含有转义字符的字符串转换成Object对象的方法
2016/12/02 Javascript
基于JavaScript实现拖动滑块效果
2017/02/16 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
apicloud拉起小程序并传递参数的方法示例
2018/11/21 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
解决Mint-ui 框架Popup和Datetime Picker组件滚动穿透的问题
2020/11/04 Javascript
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
Python SqlAlchemy动态添加数据表字段实例解析
2018/02/07 Python
pip安装py_zipkin时提示的SSL问题对应
2018/12/29 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
美国诺德斯特龙百货官网:Nordstrom
2016/08/23 全球购物
新闻专业个人自我评价
2013/09/21 职场文书
2013年学期结束动员演讲稿
2014/01/07 职场文书
《孙权劝学》教学反思
2014/04/23 职场文书
艾滋病宣传活动总结
2014/05/08 职场文书
小学社团活动总结
2014/06/27 职场文书
初中学生操行评语
2014/12/26 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
第28个世界无烟日活动总结
2015/02/10 职场文书
消防演习通知
2015/04/25 职场文书