分页是我们前端开发中经常要用到的一个组件,也有很多人提供了这样的组件,比如jquery.page.js、layer等等,都比较好用,几天我们就自己用vue来撸一个page组件,首先先来看看最终完成的效果
就是一个这样的,很简单的组件。
老规矩,先看下html结构
<div class="page-box">
<a href="javascript:;" :data-page="currPage - 1" v-if="hasPre" @click="goPre()">上一页</a>
<a href="javascript:;" data-page="1" title="首页" v-if="hasHome" @click="goPage(1)">首页</a>
<span v-if="hasFirstDot">…</span>
<a href="javascript:;" v-for="(item, index) in pageData" :data-page="item" :class="{'page-curr': item == currPage}" @click="changePage(index, item)">{{item}}</a>
<span v-if="hasLastDot">…</span>
<a href="javascript:;" class="page-last" title="尾页" :data-page="pageTotal" v-if="hasLast" @click="goPage(pageTotal)">末页</a>
<a href="javascript:;" class="page-next" :data-page="currPage+1" v-if="hasNext" @click="goNext()">下一页</a>
<span class="page-total">
到第
<input type="number" min="1" v-model="toPage">
页
<button type="button" @click="goPage(toPage)">确定</button>
</span>
</div>
从结构可以看出,我们用到几个boolean变量来控制按钮的显示,这也是vue的优势所在,我们不用写一个很长的function的来判断要怎么生成html代码,最后push到节点内。
这几个变量分别是
hasPre: false, //控制下一页按钮显示
hasNext: true, //控制上一页按钮显示
hasHome: false, //控制首页按钮显示
hasLast: true, //控制末页按钮显示
hasFirstDot: false, //控制第一个省略点显示
hasLastDot: true, //控制第二个省略点显示
每次点击都重新通过一个createData的方法来生成新的显示页码
createData (page) {
var data = [];
//两种极端
if(page - this.prifix <= 0 && this.pageTotal < 5){
for (var i = 0; i < this.pageTotal; i++) {
data.push(i + 1)
}
return data;
}
if(page + this.prifix >= this.pageTotal){
for (var i = this.pageTotal; i > this.pageTotal - 5; i--) {
data.push(i)
}
return data.reverse();
}
var left = [],right = [];
var ix = 1;
if(page < 5){
for(var i=1; i < page; i++){
var temp = page - ix
if(temp <= 0) break;
left.push(temp)
ix ++
}
}else{
for(var i=page-2; i < page; i++){
var temp = page - ix
if(temp <= 0) break;
left.push(temp)
ix ++
}
}
left.reverse()
left.push(page)
if(page < 5){
var idx = 1;
for(var j=page; j < 5; j++){
var temp_right = page + idx
right.push(temp_right)
idx ++
}
}else{
var idx = 1;
for(var j=page; j < page + this.prifix; j++){
var temp_right = page + idx
right.push(temp_right)
idx ++
}
}
left.push.apply(left,right); //合并数组
return left;
}
并且通过一个checkSpan方法来控制是否显示各个按钮,
checkSpan(){
if(this.currPage >= 2){
this.hasPre = true
}else{
this.hasPre = false
}
if(this.currPage >= 5){
this.hasHome = true
this.hasFirstDot = true
}else{
this.hasHome = false
this.hasFirstDot = false
}
if(this.currPage >= this.pageTotal - this.prifix){
this.hasLast = false
this.hasLastDot = false
}else{
this.hasLast = true
this.hasLastDot = true
}
if(this.currPage <= this.pageTotal - 1){
this.hasNext = true
}else{
this.hasNext = false
}
}
有了这两核心的方法这个功能已经完成大半。
下面是所有的javascript逻辑控制代码
export default {
data () {
return {
pageData: [],
currPage: 1,
hasPre: false,
hasNext: true,
hasHome: false,
hasLast: true,
hasFirstDot: false,
hasLastDot: true,
// pageTotal: 50,
prifix: 2,
toPage: 1,
}
},
props: ['pageTotal', 'curr'],
created: function () {
this.pageData = this.createData(1)
this.checkSpan()
this.currPage = this.curr;
},
methods: {
changePage (index, item) {
this.currPage = this.pageData[index]
this.toPage = this.pageData[index]
this.checkSpan(index)
this.pageData = this.createData(this.currPage)
this.$emit('pageChange', index, item);
},
goPre () {
var key = this.getKeyFromArr(this.pageData, this.currPage)
this.changePage(key*1 -1, this.currPage)
},
goNext () {
var key = this.getKeyFromArr(this.pageData, this.currPage)
this.changePage(key*1 + 1, this.currPage)
},
goPage (page) {
var key = this.getKeyFromArr(this.pageData, page)
if(key !== -1){
this.changePage(key, page)
}else{
//没有
if(page > this.pageTotal) return;
this.currPage = page
this.toPage = page
this.pageData = this.createData(page * 1)
this.checkSpan()
var key = this.getKeyFromArr(this.pageData, this.currPage)
this.$emit('pageChange', key, page);
}
},
checkSpan(){
if(this.currPage >= 2){
this.hasPre = true
}else{
this.hasPre = false
}
if(this.currPage >= 5){
this.hasHome = true
this.hasFirstDot = true
}else{
this.hasHome = false
this.hasFirstDot = false
}
if(this.currPage >= this.pageTotal - this.prifix){
this.hasLast = false
this.hasLastDot = false
}else{
this.hasLast = true
this.hasLastDot = true
}
if(this.currPage <= this.pageTotal - 1){
this.hasNext = true
}else{
this.hasNext = false
}
},
createData (page) {
var data = [];
//两种极端
// if(page -1 < 0 || page+1 > this.pageTotal) return this.pageData;
if(page - this.prifix <= 0 && this.pageTotal < 5){
for (var i = 0; i < this.pageTotal; i++) {
data.push(i + 1)
}
return data;
}
if(page + this.prifix >= this.pageTotal){
for (var i = this.pageTotal; i > this.pageTotal - 5; i--) {
data.push(i)
}
return data.reverse();
}
var left = [],right = [];
var ix = 1;
if(page < 5){
for(var i=1; i < page; i++){
var temp = page - ix
if(temp <= 0) break;
left.push(temp)
ix ++
}
}else{
for(var i=page-2; i < page; i++){
var temp = page - ix
if(temp <= 0) break;
left.push(temp)
ix ++
}
}
left.reverse()
left.push(page)
if(page < 5){
var idx = 1;
for(var j=page; j < 5; j++){
var temp_right = page + idx
right.push(temp_right)
idx ++
}
}else{
var idx = 1;
for(var j=page; j < page + this.prifix; j++){
var temp_right = page + idx
right.push(temp_right)
idx ++
}
}
left.push.apply(left,right); //合并数组
return left;
},
getKeyFromArr (arr, val) {
var key = -1;
for(var k in arr){
if(arr[k] == val){
key = k
}
}
return key
}
}
}
最后我们给他加一点样式,就大功告成了
.page-box{
-webkit-box-sizing: content-box!important;
-moz-box-sizing: content-box!important;
box-sizing: content-box!important;
display: inline-block;
vertical-align: middle;
margin: 10px 0;
font-size: 0;
}
.page-box span,.page-box a{
display: inline-block;
vertical-align: middle;
padding: 0 15px;
border: 1px solid #e2e2e2;
height: 28px;
line-height: 28px;
margin: 0 -1px 5px 0;
background-color: #fff;
color: #333;
font-size: 12px;
color: #999;
font-weight: 700;
}
.page-box .page-curr{
background-color: #009688;
color: #fff;
font-weight: 400;
text-align: center;
font-style: normal;
}
.page-box>:first-child, .page-box>:first-child em {
border-radius: 2px 0 0 2px;
}
.page-box .page-total {
height: 30px;
line-height: 30px;
margin-left: 1px;
border: none;
font-weight: 400;
}
.page-box input,.page-box button {
height: 30px;
line-height: 30px;
border: 1px solid #e2e2e2;
border-radius: 2px;
vertical-align: top;
background-color: #fff;
box-sizing: border-box!important;
width: 50px;
margin: 0 5px;
text-align: center;
}
接下来我们看怎么调用这个组件
我们只要在script里写下
import page from 你的路径
在components里写下
components: {
page
}
就成功的调用组件了,
完整的调用代码如下
<template>
<div id="demo5">
<page :pageTotal="total" :curr="currPage" v-on:pageChange="pageChange"></page>
</div>
</template>
<script type="text/javascript">
import page from '../../components/Page/index.vue'
export default {
data () {
return {
total: 15,
currPage: 2
}
},
methods: {
pageChange (index, item) {
console.info('触发',index, item)
}
},
components: {
page
}
}
</script>