用vue写一个分页器代码

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

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

  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;        

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

  1 <template>
  2     <div class="pageContainer">
  3         <!-- 当前页面展示多少条数据 -->
  4         <div class="pageSizeInner">
  5             <div class="totalCount">共 {{totalCount}} 条</div>
  6             <div class="pageSize">
  7                 <select v-model="perPageCount" @change="changePerPageCount">
  8                     <option :value="item" v-for="(item, index) in page_size" :key="index">{{item}}</option>
  9                 </select>
 10             </div>
 11         </div>
 12 
 13         <!-- 页码部分 -->
 14         <ul class="pagesInner">
 15             <!-- 上一页 -->
 16             <li class="page" :class="{noClick : pageNum == 1}" @click="preOrNext(-1)">
 17                 <span>上一页</span>
 18             </li>
 19             <!-- 页码 -->
 20             <li class="page" :class="{actived : item === pageNum}" v-for="(item, index) in displayPages" :key="index" @click="select(item)">
 21                 <span>{{item}}</span>
 22             </li>
 23             <!-- 下一页 -->
 24             <li class="page" :class="{noClick : pageNum == totalNum}" @click="preOrNext(1)">
 25                 <span>下一页</span>
 26             </li>
 27         </ul>
 28     </div>
 29 </template>
 30 
 31 <script>
 32     export default {
 33         data() {
 34             return {
 35                 totalCount: 9999,                                              // 总共多少条数据
 36                 page_size: ['100条/页', '200条/页', '300条/页', '400条/页'],    // 每页展示多少条数据
 37                 pageNum: 1,                                                    // 当前页码
 38                 totalNum: 20,                                                  // 总页码
 39                 middleSize: 5,                                                 // 中间显示几个页码
 40                 perPageCount: 0,                                               // 每页展示多少条数据
 41             }
 42         },
 43         computed: {
 44             // 展示页码
 45             displayPages() {
 46                 // ① 只展示'上一页'、'页码'、'下一页'
 47                 if(this.totalNum <= this.middleSize + 2) {
 48                     let pages = [];
 49                     for(let i=1; i<=this.totalNum; i++) {
 50                         pages.push(i);
 51                     }
 52                     return pages;
 53                 }else if(this.pageNum <= this.middleSize) { // this.pageNum <= this.middleSize+2
 54                     // ② 只展示右侧'...',只要当前页码小于或者等于要展示的中间页码时就展示
 55                     let pages = [1];
 56                     for(let i=2; i<this.middleSize+1; i++) {
 57                         pages.push(i);
 58                     }
 59                     pages.push('...');
 60                     pages.push(this.totalNum);
 61                     return pages;
 62                 }else if(this.pageNum >= this.totalNum - (this.middleSize - 1)) {
 63                     // ③ 只展示左侧'...',主要当前页码 大于或等于 总页码-(中间要展示页码的个数 - 1)就展示
 64                     let pages = [1, '...'];
 65                     for(let i=this.totalNum-this.middleSize+1; i<=this.totalNum; i++) {
 66                         pages.push(i);
 67                     }
 68                     return pages;
 69                 }else {
 70                     // ④ 展示左右两侧的'...'
 71                     let pages = [1, '...'];
 72                     // 当左右两侧的...都展示时,中间的页码该如何展示呢?其实就是 当前页码 - (中间要展示页码的个数/2向下取整) 到 当前页码 + (中间要展示页码的个数/2向下取整)即可
 73                     const half = Math.floor(this.middleSize/2); // 向下取整
 74                     for(let i=this.pageNum-half; i<=this.pageNum+half; i++) {
 75                         pages.push(i);
 76                     }
 77                     pages.push('...');
 78                     pages.push(this.totalNum);
 79                     return pages;                    
 80                 }
 81             }
 82         },
 83         mounted() {
 84             // 每页展示多少条数据
 85             this.perPageCount = this.page_size[0];
 86             // 计算总页码是多少
 87             this.totalNum = Math.ceil(this.totalCount/parseInt(this.perPageCount));
 88         },
 89         methods: {
 90             // 点击'上一页'、'下一页'
 91             preOrNext(n) {
 92                 this.pageNum = this.pageNum + n;
 93                 this.pageNum <= 1 ? this.pageNum = 1 : this.pageNum > this.totalNum ? this.pageNum = this.totalNum : null;
 94                 // 作为子组件,当前页码发生改变时需要通知父组件
 95                 // this.$emit('pageNumChanged', this.pageNum);
 96             },
 97             // 点击'页码'
 98             select(item) {
 99                 if(typeof item === 'string') return;
100                 if(item == this.pageNum) return;
101                 this.pageNum = item;
102                 // 作为子组件,当前页码发生改变时需要通知父组件
103                 // this.$emit('pageNumChanged', this.pageNum);
104             },
105             // 选择页面展示条数,重新计算总页码
106             changePerPageCount() {
107                 this.totalNum = Math.ceil(this.totalCount/parseInt(this.perPageCount));
108             }
109         }
110     }
111 </script>
112 
113 <style lang="scss" type="text/css">
114     .pageContainer {
115         display: flex;
116         justify-content: space-between;
117         .pageSizeInner {
118             padding-top: 9px;
119             .totalCount {
120                 display: inline-block;
121                 margin-right: 5px;
122             }
123             .pageSize {
124                 display: inline-block;
125                 >select {
126                     padding: 0 3px;
127                      100px;
128                     height: 30px;
129                     font-size: 12px;
130                     border: 1px solid #eee;
131                     border-radius: 2px;
132                     box-sizing: border-box;
133                     outline: none;
134                 }
135             }
136         }
137         .pagesInner {
138             display: inline-block;
139             text-align: center;
140             font-size: 0;
141             li {
142                 display: inline-block;
143                 margin: 5px;
144                 list-style: none;
145                 >span {
146                     display: block;
147                      46px;
148                     height: 36px;
149                     line-height: 36px;
150                     text-align: center;
151                     font-size: 12px;
152                     border: 1px solid #eee;
153                     border-radius: 5px;
154                     cursor: pointer;
155                 }
156                 &.noClick {
157                     >span {
158                         cursor: no-drop;
159                         // border-color: transparent;
160                     }
161                 }
162                 &.actived {
163                     >span {
164                         border-color: #2d8cf0;
165                         background-color: #2d8cf0;
166                         color: #fff;
167                     }
168                 }
169             }
170         }
171     }
172 </style>
View Code

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

原文地址:https://www.cnblogs.com/carriezhao/p/11102518.html