一个可复用的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 相关文章推荐
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
Dec 27 Javascript
javascript Keycode对照表
Oct 24 Javascript
A标签中通过href和onclick传递的this对象实现思路
Apr 19 Javascript
jQuery文件上传插件Uploadify使用指南
Jun 05 Javascript
Javascript基础知识(二)事件
Sep 29 Javascript
js验证身份证号有效性并提示对应信息
Oct 19 Javascript
JavaScript“尽快失败”的原则实例详解
Oct 08 Javascript
jquery UI实现autocomplete在获取焦点时得到显示列表功能示例
Jun 04 jQuery
vue输入节流,避免实时请求接口的实例代码
Oct 30 Javascript
Paypal支付不完全指北
Jun 04 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
Jun 05 Javascript
vue实现页面切换滑动效果
Jun 29 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也可以?成Shell Script
2006/10/09 PHP
PHP5.2下chunk_split()函数整数溢出漏洞 分析
2007/06/06 PHP
php 404错误页面实现代码
2009/06/22 PHP
通用PHP动态生成静态HTML网页的代码
2010/03/04 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
laravel 实现用户登录注销并限制功能
2019/10/24 PHP
TopList标签和JavaScript结合两例
2007/08/12 Javascript
jQuery select控制插件
2009/08/17 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
javascript 得到文件后缀名的思路及实现
2020/05/09 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
js正则表达式校验指定字符串的方法
2018/07/23 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
2018/09/14 Javascript
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
2020/06/05 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
在实例中重学JavaScript事件循环
2020/12/03 Javascript
[51:43]OG vs LGD 2018国际邀请赛淘汰赛BO3 第五场 8.26
2018/08/30 DOTA
Python扫描IP段查看指定端口是否开放的方法
2015/06/09 Python
Python抓取百度查询结果的方法
2015/07/08 Python
Python贪吃蛇游戏编写代码
2020/10/26 Python
在django view中给form传入参数的例子
2019/07/19 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
Python字符串对齐、删除字符串不需要的内容以及格式化打印字符
2021/01/23 Python
使用CSS3的背景渐变Text Gradient 创建文字颜色渐变
2014/08/19 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
调解协议书
2014/04/16 职场文书
党性心得体会
2014/09/03 职场文书
给朋友的道歉短信
2015/05/12 职场文书
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python
python中sqllite插入numpy数组到数据库的实现方法
2021/06/21 Python
Python max函数中key的用法及原理解析
2021/06/26 Python
Python中非常使用的6种基本变量的操作与技巧
2022/03/22 Python