Vue.js分页组件实现:diVuePagination的使用详解

一.介绍

Vue.js 是什么

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

二.创建初始化项目

这里不在详细说明,我们的分页演示只需要vue和vue-router就可以了,我们直接构建项目和设置配置。

main.js:

import Vue from \'vue\'
import App from \'./App.vue\'
import VueRouter from \'vue-router\'
import pageHome from \'./pageHome.vue\'
import pageNews from \'./pageNews.vue\'
import pageInfo from \'./pageInfo.vue\'
//路由配置
Vue.use(VueRouter);
var routes = [
 { path: \'/\', component: pageHome},
 { path: \'/pageNews\', component: pageNews},
 { path: \'/pageInfo\', component: pageInfo}
]
var router = new VueRouter({
 routes: routes // (缩写)相当于 routes: routes
})
new Vue({
 el: \'#app\',
 router,
 render: h => h(App)
})

App.vue:

<template>
 <div id=\"app\">
 <h3>{{msg}}</h3>
 <ul>
 <li><router-link to=\"/\">pageHome</router-link></li>
 <li><router-link to=\"/pageNews\">pageNews</router-link></li>
 <li><router-link to=\"/pageInfo\">pageInfo</router-link></li>
 </ul>
 <div>
 <router-view></router-view>
 </div>
 </div>
</template>
<script>
export default {
 name: \'app\',
 data () {
 return {
 msg: \'分页组件:DiVuePage \'
 }
 }
}
</script>
<style>
#app {
 font-family: \'Avenir\', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

pageHome.vue:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-7页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 </div>
</template>
<script>
export default {
 name: \'pageHome\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-7页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=7
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==4){
 list=[
 {id:1,text:\"161616\"},
 {id:2,text:\"171717\"},
 {id:3,text:\"181818\"},
 {id:4,text:\"191919\"},
 {id:5,text:\"202020\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==5){
 list=[
 {id:1,text:\"2121\"},
 {id:2,text:\"22222\"},
 {id:3,text:\"232323\"},
 {id:4,text:\"242424\"},
 {id:5,text:\"252525\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==6){
 list=[
 {id:1,text:\"2626\"},
 {id:2,text:\"2727\"},
 {id:3,text:\"2828\"},
 {id:4,text:\"2929\"},
 {id:5,text:\"3030\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==7){
 list=[
 {id:1,text:\"3131\"},
 {id:2,text:\"3232\"}
 ]
 allpage=7
 nextpage=false; 
 };
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

pageInfo.vue:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-3页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 </div>
</template>
<script>
export default {
 name: \'pageInfo\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-3页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=3
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=3
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=3
 nextpage=false; 
 }
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

pageNews.vue:

<template>
 <div class=\"page\">
 <p>模拟ajax数据 1页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 </div>
</template>
<script>
export default {
 name: \'pageNews\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"}
 ]
 allpage=1
 nextpage=false;
 }
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

预览效果:

Vue.js分页组件实现:diVuePagination的使用详解

三.分页静态结构和样式

divuePage.vue:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\">第一页</div>
 <div class=\"DiReactPage-btn disable\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span class=\"active\">1</span>
 <span>2</span>
 <span>3</span>
 <span>4</span>
 </div>
 <div class=\"DiReactPage-btn\">下一页</div>
 <div class=\"DiReactPage-btn\">最后一页</div>
 <div class=\"DiReactPage-btn\">总4页</div>
 <input class=\"DiReactPage-input\" type=\"text\" />
 <button class=\"DiReactPage-btn\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 data () {
 return {
 pages:[1,2,3,4,5]
 }
 },
 methods:{
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

main.js注册:

import Vue from \'vue\'
import App from \'./App.vue\'
import VueRouter from \'vue-router\'
import pageHome from \'./pageHome.vue\'
import pageNews from \'./pageNews.vue\'
import pageInfo from \'./pageInfo.vue\'
//注册组件
import divuePage from \'./divuePage.vue\'
Vue.component(\'divue-page\', divuePage)
//路由配置
Vue.use(VueRouter);
var routes = [
 { path: \'/\', component: pageHome},
 { path: \'/pageNews\', component: pageNews},
 { path: \'/pageInfo\', component: pageInfo}
]
var router = new VueRouter({
 routes: routes // (缩写)相当于 routes: routes
})
new Vue({
 el: \'#app\',
 router,
 render: h => h(App)
})

pageHome.vue引用:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-7页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 <divue-page></divue-page>
 </div>
</template>
<script>
export default {
 name: \'pageHome\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-7页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=7
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==4){
 list=[
 {id:1,text:\"161616\"},
 {id:2,text:\"171717\"},
 {id:3,text:\"181818\"},
 {id:4,text:\"191919\"},
 {id:5,text:\"202020\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==5){
 list=[
 {id:1,text:\"2121\"},
 {id:2,text:\"22222\"},
 {id:3,text:\"232323\"},
 {id:4,text:\"242424\"},
 {id:5,text:\"252525\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==6){
 list=[
 {id:1,text:\"2626\"},
 {id:2,text:\"2727\"},
 {id:3,text:\"2828\"},
 {id:4,text:\"2929\"},
 {id:5,text:\"3030\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==7){
 list=[
 {id:1,text:\"3131\"},
 {id:2,text:\"3232\"}
 ]
 allpage=7
 nextpage=false; 
 };
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

效果预览:

Vue.js分页组件实现:diVuePagination的使用详解

四.分页组件实现逻辑分析

我们分析一下如何实现我们的分页组件:

从分页组件考虑:

分页组件需要显示页数,那么就需要传递给分页组件总用多少页这个状态,

上一页和下一页存在不可用状态,在第一页上一页不可用,所以要把当前所在页数传递,同样页数的焦点位置也需要它判断,

然后就是方法,我们页数和按钮的点击都是发起请求,携带的参数就是当前点击的页数,

1.总页数,当前所在页,可在父组件传递进入

2.发起请求的方法可以通过组件交互通信实现

1的数据都是接口会返回给我们的,我们直接以属性传递即可:

Vue.js分页组件实现:diVuePagination的使用详解

2的实现也很简单,我们其实已经处理模拟使用过了:

Vue.js分页组件实现:diVuePagination的使用详解

我们只需要自定义事件,让分页组件$emit即可:

Vue.js分页组件实现:diVuePagination的使用详解

pageHome.vue:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-7页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 <divue-page v-bind:currentpage=\"currentpage\" v-bind:allpage=\"allpage\" v-on:getajaxlist=\"getajaxlist\"></divue-page>
 </div>
</template>
<script>
export default {
 name: \'pageHome\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-7页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=7
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==4){
 list=[
 {id:1,text:\"161616\"},
 {id:2,text:\"171717\"},
 {id:3,text:\"181818\"},
 {id:4,text:\"191919\"},
 {id:5,text:\"202020\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==5){
 list=[
 {id:1,text:\"2121\"},
 {id:2,text:\"22222\"},
 {id:3,text:\"232323\"},
 {id:4,text:\"242424\"},
 {id:5,text:\"252525\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==6){
 list=[
 {id:1,text:\"2626\"},
 {id:2,text:\"2727\"},
 {id:3,text:\"2828\"},
 {id:4,text:\"2929\"},
 {id:5,text:\"3030\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==7){
 list=[
 {id:1,text:\"3131\"},
 {id:2,text:\"3232\"}
 ]
 allpage=7
 nextpage=false; 
 };
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

五.分页组件逻辑编写

divuePage.vue我们接受了这些传递的内容,总页数和当前所在页,然后点击第一页触发自定义事件,传递给父组件一个1,获取第一页数据:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\" v-on:click=\"clickFirst\">第一页</div>
 <div class=\"DiReactPage-btn disable\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span class=\"active\">1</span>
 <span>2</span>
 <span>3</span>
 <span>4</span>
 </div>
 <div class=\"DiReactPage-btn\">下一页</div>
 <div class=\"DiReactPage-btn\">最后一页</div>
 <div class=\"DiReactPage-btn\">总4页</div>
 <input class=\"DiReactPage-input\" type=\"text\" />
 <button class=\"DiReactPage-btn\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 props:[\"currentpage\",\"allpage\"],
 methods:{
 clickFirst:function(){//点击第一页 
 this.$emit(\"getajaxlist\",1);
 }
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

1.页数显示

我们的首要工作就是把页数显示出来,我们已经接收了总页数,其实这个问题很容易解决,我们设置一个计算属性,属性依据总页数生成一个数组,从1到n即可:

Vue.js分页组件实现:diVuePagination的使用详解

显示:

Vue.js分页组件实现:diVuePagination的使用详解

这样还不够健壮,还有一个就是总页数5做分界线,大于5就显示当前到后4个,

比如在第3页,显示:3 4 5 6 7

第2页,显示:2 3 4 5 6

好了我们加入一些小的逻辑判断:

Vue.js分页组件实现:diVuePagination的使用详解

我们要给当前页加一个类名标识,已经获取当前的页数了,我们加一个判断就可以了,在v-for中:

Vue.js分页组件实现:diVuePagination的使用详解

我们在加入点击事件,拿到点击的item就是要请求后台数据的参数page:

Vue.js分页组件实现:diVuePagination的使用详解

定义这个方法:

Vue.js分页组件实现:diVuePagination的使用详解

完整代码:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\" v-on:click=\"clickFirst\">第一页</div>
 <div class=\"DiReactPage-btn disable\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span v-for=\"(item,index) in pages\" v-bind:class=\"{active:currentpage==item}\" v-on:click=\"clickCurrent(item)\">{{item}}</span>
 </div>
 <div class=\"DiReactPage-btn\">下一页</div>
 <div class=\"DiReactPage-btn\">最后一页</div>
 <div class=\"DiReactPage-btn\">总4页</div>
 <input class=\"DiReactPage-input\" type=\"text\" />
 <button class=\"DiReactPage-btn\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 computed:{
 pages:function(){
 var arr=[];
 if(this.allpage>5){
 if(this.currentpage+5>this.allpage){
 for(var i=this.currentpage;i<=this.allpage;i++){
 arr.push(i);
 };
 }else{
 for(var i=this.currentpage;i<this.currentpage+5;i++){
 arr.push(i);
 };
 };
 }else{
 for(var i=1;i<=this.allpage;i++){
 arr.push(i);
 };
 }
 return arr;
 }
 },
 props:[\"currentpage\",\"allpage\"],
 methods:{
 clickFirst:function(){//点击第一页 
 this.$emit(\"getajaxlist\",1);
 },
 clickCurrent:function(item){
 this.$emit(\"getajaxlist\",item);
 }
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

效果测试:

Vue.js分页组件实现:diVuePagination的使用详解

2.第一页和最后一页处理

这个很简单,只是传递page参数,我们已经获取总页数,直接设置即可!

Vue.js分页组件实现:diVuePagination的使用详解

Vue.js分页组件实现:diVuePagination的使用详解

3.上一页和下一页处理

这个对比第一页需要加入特殊的处理,当前是第一页,这个按钮就不可用状态,下一页一样的逻辑判断当前是不是在最后一页:

Vue.js分页组件实现:diVuePagination的使用详解

调用位置加入事件,在加一个是否可用的类名:

Vue.js分页组件实现:diVuePagination的使用详解

全部代码:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\" v-on:click=\"clickFirst\">第一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickPrev\" v-bind:class=\"{disable:currentpage==1}\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span v-for=\"(item,index) in pages\" v-bind:class=\"{active:currentpage==item}\" v-on:click=\"clickCurrent(item)\">{{item}}</span>
 </div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickNext\" v-bind:class=\"{disable:currentpage==allpage}\">下一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickLast\">最后一页</div>
 <div class=\"DiReactPage-btn\">总4页</div>
 <input class=\"DiReactPage-input\" type=\"text\" />
 <button class=\"DiReactPage-btn\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 computed:{
 pages:function(){
 var arr=[];
 if(this.allpage>5){
 if(this.currentpage+5>this.allpage){
 for(var i=this.currentpage;i<=this.allpage;i++){
 arr.push(i);
 };
 }else{
 for(var i=this.currentpage;i<this.currentpage+5;i++){
 arr.push(i);
 };
 };
 }else{
 for(var i=1;i<=this.allpage;i++){
 arr.push(i);
 };
 }
 return arr;
 }
 },
 props:[\"currentpage\",\"allpage\"],
 methods:{
 clickFirst:function(){//点击第一页 
 this.$emit(\"getajaxlist\",1);
 },
 clickCurrent:function(item){
 this.$emit(\"getajaxlist\",item);
 },
 clickLast:function(){//点击最后一页
 this.$emit(\"getajaxlist\",this.allpage);
 },
 clickPrev:function(){//点击上一页
 if(this.currentpage-1<1){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage-1);
 },
 clickNext:function(){//点击下一页
 if(this.currentpage+1>this.allpage){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage+1);
 }
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

效果测试:

Vue.js分页组件实现:diVuePagination的使用详解

4.跳页处理

这个我们获取输入框的值,直接调用,不过对输入的内容必须有一些判断限制:

Vue.js分页组件实现:diVuePagination的使用详解

加一个data:

Vue.js分页组件实现:diVuePagination的使用详解

使用位置:

Vue.js分页组件实现:diVuePagination的使用详解

5.显示总页数

这个是最简单的:

Vue.js分页组件实现:diVuePagination的使用详解

六.分页全部代码和测试

divuePage.vue:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\" v-on:click=\"clickFirst\">第一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickPrev\" v-bind:class=\"{disable:currentpage==1}\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span v-for=\"(item,index) in pages\" v-bind:class=\"{active:currentpage==item}\" v-on:click=\"clickCurrent(item)\">{{item}}</span>
 </div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickNext\" v-bind:class=\"{disable:currentpage==allpage}\">下一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickLast\">最后一页</div>
 <div class=\"DiReactPage-btn\">总{{allpage}}页</div>
 <input class=\"DiReactPage-input\" type=\"text\" v-model=\"skipvalue\" />
 <button class=\"DiReactPage-btn\" v-on:click=\"clickSkip\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 computed:{
 pages:function(){
 var arr=[];
 if(this.allpage>5){
 if(this.currentpage+5>this.allpage){
 for(var i=this.currentpage;i<=this.allpage;i++){
 arr.push(i);
 };
 }else{
 for(var i=this.currentpage;i<this.currentpage+5;i++){
 arr.push(i);
 };
 };
 }else{
 for(var i=1;i<=this.allpage;i++){
 arr.push(i);
 };
 }
 return arr;
 }
 },
 data:function(){
 return {
 skipvalue:\"\"
 }
 },
 props:[\"currentpage\",\"allpage\"],
 methods:{
 clickFirst:function(){//点击第一页 
 this.$emit(\"getajaxlist\",1);
 },
 clickCurrent:function(item){
 this.$emit(\"getajaxlist\",item);
 },
 clickLast:function(){//点击最后一页
 this.$emit(\"getajaxlist\",this.allpage);
 },
 clickPrev:function(){//点击上一页
 if(this.currentpage-1<1){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage-1);
 },
 clickNext:function(){//点击下一页
 if(this.currentpage+1>this.allpage){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage+1);
 },
 clickSkip:function(){//点击下一页
 if(isNaN(this.skipvalue)){
 console.log(\"必须是数字\")
 return false;
 }
 if(this.skipvalue<1 || this.skipvalue>this.allpage){
 console.log(\"超过范围\")
 return false;
 }
 this.$emit(\"getajaxlist\",this.skipvalue);
 }
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

我们现在在pageHome.vue做了使用,这个模拟数据包含7页,我们在另外两个组件也使用分页组件,测试小于5页和只有1页的效果:

<divue-page v-bind:currentpage=\"currentpage\" v-bind:allpage=\"allpage\" v-on:getajaxlist=\"getajaxlist\"></divue-page>

直接粘贴就可以在另外的组件使用。

只有1页:

Vue.js分页组件实现:diVuePagination的使用详解

小于5页:

Vue.js分页组件实现:diVuePagination的使用详解

测试没有太大问题!

七.优化和改进建议

当然不是样式的优化,这个需要设计的参与,我们还是显示的优化和改进,比如:

Vue.js分页组件实现:diVuePagination的使用详解

我们是不是该有一个…

还有就是…

可以参考别的分页效果,然后你可以不断的改进!

八.完整代码

main.js:

import Vue from \'vue\'
import App from \'./App.vue\'
import VueRouter from \'vue-router\'
import pageHome from \'./pageHome.vue\'
import pageNews from \'./pageNews.vue\'
import pageInfo from \'./pageInfo.vue\'
//注册组件
import divuePage from \'./divuePage.vue\'
Vue.component(\'divue-page\', divuePage)
//路由配置
Vue.use(VueRouter);
var routes = [
 { path: \'/\', component: pageHome},
 { path: \'/pageNews\', component: pageNews},
 { path: \'/pageInfo\', component: pageInfo}
]
var router = new VueRouter({
 routes: routes // (缩写)相当于 routes: routes
})
new Vue({
 el: \'#app\',
 router,
 render: h => h(App)
})

App.vue:

<template>
 <div id=\"app\">
 <h3>{{msg}}</h3>
 <ul>
 <li><router-link to=\"/\">pageHome</router-link></li>
 <li><router-link to=\"/pageNews\">pageNews</router-link></li>
 <li><router-link to=\"/pageInfo\">pageInfo</router-link></li>
 </ul>
 <div>
 <router-view></router-view>
 </div>
 </div>
</template>
 
<script>
export default {
 name: \'app\',
 data () {
 return {
 msg: \'分页组件:DiVuePage \'
 }
 }
}
</script>
 
<style>
#app {
 font-family: \'Avenir\', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

divuePage.vue:

<template>
 <div class=\"DiReactPage\">
 <div class=\"DiReactPage-btn\" v-on:click=\"clickFirst\">第一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickPrev\" v-bind:class=\"{disable:currentpage==1}\">上一页</div>
 <div class=\"DiReactPage-page\">
 <span v-for=\"(item,index) in pages\" v-bind:class=\"{active:currentpage==item}\" v-on:click=\"clickCurrent(item)\">{{item}}</span>
 </div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickNext\" v-bind:class=\"{disable:currentpage==allpage}\">下一页</div>
 <div class=\"DiReactPage-btn\" v-on:click=\"clickLast\">最后一页</div>
 <div class=\"DiReactPage-btn\">总{{allpage}}页</div>
 <input class=\"DiReactPage-input\" type=\"text\" v-model=\"skipvalue\" />
 <button class=\"DiReactPage-btn\" v-on:click=\"clickSkip\">跳转</button>
 </div>
</template>
<script>
export default {
 name: \'divuePage\',
 computed:{
 pages:function(){
 var arr=[];
 if(this.allpage>5){
 if(this.currentpage+5>this.allpage){
 for(var i=this.currentpage;i<=this.allpage;i++){
 arr.push(i);
 };
 }else{
 for(var i=this.currentpage;i<this.currentpage+5;i++){
 arr.push(i);
 };
 };
 }else{
 for(var i=1;i<=this.allpage;i++){
 arr.push(i);
 };
 }
 return arr;
 }
 },
 data:function(){
 return {
 skipvalue:\"\"
 }
 },
 props:[\"currentpage\",\"allpage\"],
 methods:{
 clickFirst:function(){//点击第一页 
 this.$emit(\"getajaxlist\",1);
 },
 clickCurrent:function(item){
 this.$emit(\"getajaxlist\",item);
 },
 clickLast:function(){//点击最后一页
 this.$emit(\"getajaxlist\",this.allpage);
 },
 clickPrev:function(){//点击上一页
 if(this.currentpage-1<1){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage-1);
 },
 clickNext:function(){//点击下一页
 if(this.currentpage+1>this.allpage){
 return false;
 }
 this.$emit(\"getajaxlist\",this.currentpage+1);
 },
 clickSkip:function(){//点击下一页
 if(isNaN(this.skipvalue)){
 console.log(\"必须是数字\")
 return false;
 }
 if(this.skipvalue<1 || this.skipvalue>this.allpage){
 console.log(\"超过范围\")
 return false;
 }
 this.$emit(\"getajaxlist\",this.skipvalue);
 }
 }
}
</script>
<style>
 .DiReactPage{ height:30px; line-height:30px; text-align:center;}
 .DiReactPage .DiReactPage-btn{ display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; border-radius:4px; background:#09F; cursor:pointer;}
 .DiReactPage .DiReactPage-btn.disable{ background:#999;cursor:not-allowed;}
 .DiReactPage .DiReactPage-page{ display:inline-block; height:30px; line-height:30px; margin:0 20px;}
 .DiReactPage .DiReactPage-page span{display:inline-block; height:30px; line-height:30px; padding:0 5px; margin:0 5px; color:#000; cursor:pointer;}
 .DiReactPage .DiReactPage-page span.active{ color:#09F; }
 .DiReactPage .iReactPage-input{ width:100px; border:1px solid #666; border-radius:4px;height:30px; line-height:30px; }
</style>

pageHome.vue:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-7页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 <divue-page v-bind:currentpage=\"currentpage\" v-bind:allpage=\"allpage\" v-on:getajaxlist=\"getajaxlist\"></divue-page>
 </div>
</template>
<script>
export default {
 name: \'pageHome\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-7页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=7
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==4){
 list=[
 {id:1,text:\"161616\"},
 {id:2,text:\"171717\"},
 {id:3,text:\"181818\"},
 {id:4,text:\"191919\"},
 {id:5,text:\"202020\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==5){
 list=[
 {id:1,text:\"2121\"},
 {id:2,text:\"22222\"},
 {id:3,text:\"232323\"},
 {id:4,text:\"242424\"},
 {id:5,text:\"252525\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==6){
 list=[
 {id:1,text:\"2626\"},
 {id:2,text:\"2727\"},
 {id:3,text:\"2828\"},
 {id:4,text:\"2929\"},
 {id:5,text:\"3030\"},
 ]
 allpage=7
 nextpage=true; 
 }else if(currentpage==7){
 list=[
 {id:1,text:\"3131\"},
 {id:2,text:\"3232\"}
 ]
 allpage=7
 nextpage=false; 
 };
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

pageInfo.vue:

<template>
 <div class=\"page\">
 <p>//模拟ajax数据 1-3页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 <divue-page v-bind:currentpage=\"currentpage\" v-bind:allpage=\"allpage\" v-on:getajaxlist=\"getajaxlist\"></divue-page>
 </div>
</template>
<script>
export default {
 name: \'pageInfo\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1-3页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"},
 {id:4,text:\"44444444444\"},
 {id:5,text:\"555555555\"},
 ]
 allpage=3
 nextpage=true;
 }else if(currentpage==2){
 list=[
 {id:1,text:\"66666666\"},
 {id:2,text:\"7777777777\"},
 {id:3,text:\"8888888888\"},
 {id:4,text:\"99999999999\"},
 {id:5,text:\"101010\"},
 ]
 allpage=3
 nextpage=true; 
 }else if(currentpage==3){
 list=[
 {id:1,text:\"111111111111111\"},
 {id:2,text:\"121212\"},
 {id:3,text:\"131313\"},
 {id:4,text:\"141414\"},
 {id:5,text:\"15515\"},
 ]
 allpage=3
 nextpage=false; 
 }
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

pageNews.vue:

<template>
 <div class=\"page\">
 <p>模拟ajax数据 1页</p>
 <ul class=\"ull\">
 <li v-for=\"(item,index) in list\"><span class=\"l\">id:{{item.id}}</span> <span class=\"r\">内容:{{item.text}}</span></li>
 </ul>
 <divue-page v-bind:currentpage=\"currentpage\" v-bind:allpage=\"allpage\" v-on:getajaxlist=\"getajaxlist\"></divue-page>
 </div>
</template>
<script>
export default {
 name: \'pageNews\',
 data () {
 return {
 currentpage:0,
 list: [],
 allpage:\"\",
 nextpage:false
 }
 },
 methods:{
 getajaxlist:function(currentpage){
 var that=this;
 var list=[];
 var allpage=\"\";
 var nextpage=\"\";
 //模拟ajax数据 1页
 setTimeout(function(){ 
 if(currentpage==1){
 list=[
 {id:1,text:\"111111\"},
 {id:2,text:\"222222\"},
 {id:3,text:\"3333333333\"}
 ]
 allpage=1
 nextpage=false;
 }
 that.currentpage=currentpage;
 that.list=list;
 that.allpage=allpage;
 that.nextpage=nextpage;
 },200); 
 }
 },
 created:function(){
 //模拟生成第一页数据
 this.getajaxlist(1);
 }
}
</script>
<style>
 ul{ list-style:none;}
 ull{ margin:100px auto; width:1000px;line-height:30px;}
 li{height:30px;}
 .l{float:left;width:300px;}
 .r{float:left;width:600px;}
</style>

以上所述是小编给大家介绍的Vue.js分页组件实现:diVuePagination的使用详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容