一个可复用的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 相关文章推荐
vs2003 js文件编码问题的解决方法
Mar 20 Javascript
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
May 07 Javascript
javascript 触发HTML元素绑定的函数
Sep 11 Javascript
jQuery获取对象简单实现方法小结
Oct 30 Javascript
基于Jquery实现仿百度百科右侧导航代码附源码下载
Nov 27 Javascript
jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
Dec 03 Javascript
使用Node.js实现RESTful API的示例
Aug 01 Javascript
使用Vuex实现一个笔记应用的方法
Mar 13 Javascript
Vue使用mixins实现压缩图片代码
Mar 14 Javascript
Bootstrap Fileinput 4.4.7文件上传实例详解
Jul 25 Javascript
如何封装了一个vue移动端下拉加载下一页数据的组件
Jan 06 Javascript
VUE单页面切换动画代码(全网最好的切换效果)
Oct 31 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
PHP数据流应用的一个简单实例
2012/09/14 PHP
Redis构建分布式锁
2017/03/28 PHP
tp5递归 无限级分类详解
2019/10/18 PHP
YII2框架中日志的配置与使用方法实例分析
2020/03/18 PHP
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
让你的网站可编辑的实现js代码
2009/10/19 Javascript
jQuery 开发者应该注意的9个错误
2012/05/03 Javascript
js跑步算法的实现代码
2013/12/04 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
全面解析jQuery $(document).ready()和JavaScript onload事件
2016/06/08 Javascript
JS实现点击事件统计的简单实例
2016/07/10 Javascript
Select2.js下拉框使用小结
2016/10/24 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
JavaScript图片处理与合成总结
2018/03/04 Javascript
Angular异步变同步处理方法
2018/08/13 Javascript
vue过滤器实现日期格式化的案例分析
2020/07/02 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
2020/08/22 Javascript
[48:48]完美世界DOTA2联赛PWL S3 Magama vs GXR 第一场 12.19
2020/12/24 DOTA
python数组复制拷贝的实现方法
2015/06/09 Python
浅谈Python中eval的强大与危害
2019/03/13 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
2019/04/29 Python
在django中form的label和verbose name的区别说明
2020/05/20 Python
使用HTML5技术开发一个属于自己的超酷颜色选择器
2013/09/22 HTML / CSS
HTML5中5个简单实用的API
2014/04/28 HTML / CSS
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
应届生体育教师自荐信
2013/10/03 职场文书
事业单位请假制度
2014/01/13 职场文书
运动会广播稿500字
2014/01/28 职场文书
《和田的维吾尔》教学反思
2014/04/14 职场文书
大学第二课堂活动总结
2014/07/08 职场文书
购房委托书范本
2014/09/18 职场文书
中学生旷课检讨书2篇
2014/10/09 职场文书
校车安全管理责任书
2015/05/11 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
详解Go语言中Get/Post请求测试
2022/06/01 Golang