Vue.js分页组件实现:diVuePagination

时间:2022-12-20 08:48:00

完整版下载地址:https://gitee.com/dgx/diVuePagination

完整版演示地址:http://dgx.gitee.io/divuepagination/#/

 

一.准备工总

利用vue-cli和webpack如何快速搭建一个项目我们已经有过介绍:

为vue开发准备的一份es6语法笔记  https://my.oschina.net/tbd/blog/1541903

Vue.js构建项目笔记1:vue-cli  https://my.oschina.net/tbd/blog/1552953

Vue.js构建项目笔记2:vuejs+vue-router  https://my.oschina.net/tbd/blog/1553267

Vue.js构建项目笔记3:vuejs+vue-router +vuex  https://my.oschina.net/tbd/blog/1553518

至于vue的语法学习,官网让你最快速掌握:https://cn.vuejs.org/v2/guide/

 

二.创建初始化项目

这里不在详细说明,我们的分页演示只需要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>

 

相关文章