分页组件功能:分页!,大致功能如下:
1.左右箭头页码的前移和后退
2.显示当前页数
3.显示总页数
4.手动输入跳转(当输入的数字大于总页数,跳转到最后一页,输入的页数小于1,跳转到第一页)
5.当页数小于等于1,不显示分页组件
6.当分页数数量庞大时,省略号形式的实现
代码结构
<template>
<div class="page" >
<div class="pagelist">
/*左箭头*/
<a href="JavaScript:void (0)">
<i class="iconfont icon-zuojiantou"></i>
</a>
/*页码数*/
<a href="JavaScript:void (0)"</a>
/*右箭头*/
<a href="JavaScript:void (0)"><i
class="iconfont icon-youjiantou"></i></a>
/*可选择的页数*/
<span>{{pageSize}}条/页</span>
/*手动输入跳转*/
<span>跳至</span>
<input>
<span class="page-font">页</span>
<a href="JavaScript:void (0)">GO</a>
</div>
</div>
</template>
逻辑组件和页面组件应该要区分开,逻辑组件是可以给多个页面组件使用的,所以在逻辑组件中不应该涉及到固定数据,都需要从页面级组件中传过来。比如颜色,样式,是否显示,功能等等。在此处就暂且接受三个不固定值
当前页,总页数,每页条数
点击事件:
1.点击左右箭头页码的加减
2.点击页数跳转到相应页面上
3.手动输入页码,点击跳转,跳转到相应页面
<template>
<div class="page" v-show="show">
<div class="pagelist">
<a href="JavaScript:void (0)" class="jump left" :class="{'disabled':pageNo<=1}" :disabled="pageNo<=1"
@click="minus()">
<i class="iconfont icon-zuojiantou"></i>
</a>
<a href="JavaScript:void (0)" class="jump" v-for="index in indexs"
v-bind:class="{ bgprimary: pageNo == index,noJump:index<1 }"
v-on:click="jumpPage(index)">{{ index < 1 ? "..." : index }}</a>
<a href="JavaScript:void (0)" class="jump right" :class="{'disabled':pageNo==pages}" @click="add()"><i
class="iconfont icon-youjiantou"></i></a>
<span class="pages">{{pageSize}}条/页</span>
<span>跳至</span>
<input class="jumpinp" type="text" v-model="changePage" @input="handleInput" @keyup.enter="jumpPage(changePage)">
<span class="page-font">页</span>
<a href="JavaScript:void (0)" class="jump gobtn" @click="jumpPage(changePage)">GO</a>
</div>
</div>
</template>
1.点击左箭头:minus()
判定条件:只有当页码>1时,才减减,并调用sendPageNo()方法,告诉page组件页码已经变化,该更新了
2.点击右箭头:add()
判定条件:只有当页码<pages(总页数)时才加加,并调用sendPageNo()方法,告诉page组件页码已经变化,该更新了
3.当页码数成千上百条时就需要隐藏部分代码了
此时就需要对页数进行处理了
indexs: function () {
var left = 1
var right = this.pages
var ar = []
if (this.pages >= 11) {//当页码数大于11时才会隐藏页码数
if (this.pageNo > 5 && this.pageNo < this.pages - 4) {
left = this.pageNo - 5
right = this.pageNo + 4
} else {
if (this.pageNo <= 5) {
left = 1
right = 10
} else {
right = this.pages
left = this.pages - 9
}
}
}
while (left <= right) {//初步处理的页码数push到创建的数组中,准备进行下一步处理
ar.push(left)
left++
}
**if (ar[0] > 1) {
ar[0] = 1
ar[1] = -1
} //上下这两步是处理数据最重要的两步,在之前的处理上把需要隐藏的部分赋值为-1,再通过三目运算符判定是否为省略号,也就是隐藏
if (ar[ar.length - 1] < this.pages) {
ar[ar.length - 1] = this.pages
ar[ar.length - 2] = 0
}**
return ar
}
}
我们需要监听变量pageNo和pageNum的变化,是分页组件很重要的一部分,目的是一旦页码改变就可以通知父组件或者本身组件改变值,从而从新触发事件
watch: {
pageNum: {
handler (newValue, oldValue) {
if (newValue != oldValue) {
this.pageNo = newValue
this.pageNum = this.pageNo
}
},
deep: 1
},
/*
* 监听子容器当前页码, update到父容器
* <compo :foo.sync="active"></compo> 语法糖会被解析成 <compo :foo="active" @update:foo="val => active = val"></compo>
* 子组件更新父组件this.$emit('update:foo', newValue)
* */
pageNo: {
handler (newValue, oldValue) {
if (newValue != oldValue) {
this.$emit('update:pageNum', newValue)
//一般子传父,触发父组件的一个事件,告知父组件应该要修改值了,但加上update:后就是直接把后面的newvalue值重新赋给父组件了
}
},
deep: 0
}
},
在手动输入这一块,需要考虑:
1.用户的不规范输入/[^\d]/g 匹配所有非数字字符 置为空
2.用户回车跳转 @keyup.enter=“jumpPage(changePage)”
3.手动点击GO跳转 @click=“jumpPage(changePage)”
jumpPage (id) {//需要对id也就是页码数进行判定,且在执行后需要清空输入框
if (id > 0) {
if (id > this.pages) {
this.changePage = this.pages
this.pageNo = this.pages
this.sendPageNo()
this.changePage = ''
} else {
this.pageNo = id * 1
this.sendPageNo()
this.changePage = ''
}
}else{
this.pageNo=1
this.sendPageNo()
this.changePage = ''
}
}
sendPageNo () {
this.$emit('getPageNum', this.pageNo)//触发父组件的事件
},
say () {
this.pageNo = 1
}
script完整代码,整合上面部分
export default {
name: 'Page',
data () {
return {
changePage: '', // 跳转页
pageNo: this.pageNum
}
},
props: ['pageNum', 'pages', 'pageSize'],
watch: {
pageNum: {
handler (newValue, oldValue) {
if (newValue != oldValue) {
this.pageNo = newValue
this.pageNum = this.pageNo
}
},
deep: 1
},
/*
* 监听子容器当前页码, update到父容器
* <compo :foo.sync="active"></compo> 语法糖会被解析成 <compo :foo="active" @update:foo="val => active = val"></compo>
* 子组件更新父组件this.$emit('update:foo', newValue)
* */
pageNo: {
handler (newValue, oldValue) {
if (newValue != oldValue) {
this.$emit('update:pageNum', newValue)
}
},
deep: 0
}
},
computed: {
show: function () {
return this.pages && this.pages != 1
},
indexs: function () {
var left = 1
var right = this.pages
var ar = []
if (this.pages >= 11) {
if (this.pageNo > 5 && this.pageNo < this.pages - 4) {
left = this.pageNo - 5
right = this.pageNo + 4
} else {
if (this.pageNo <= 5) {
left = 1
right = 10
} else {
right = this.pages
left = this.pages - 9
}
}
}
while (left <= right) {
ar.push(left)
left++
}
if (ar[0] > 1) {
ar[0] = 1
ar[1] = -1
}
if (ar[ar.length - 1] < this.pages) {
ar[ar.length - 1] = this.pages
ar[ar.length - 2] = 0
}
return ar
}
},
mounted () {
},
methods: {
handleInput (e) {
this.changePage = e.target.value.replace(/[^\d]/g, '')
},
say () {
this.pageNo = 1
},
sendPageNo () {
this.$emit('getPageNum', this.pageNo)
},
jumpPage (id) {
if (id > 0) {
if (id > this.pages) {
this.changePage = this.pages
this.pageNo = this.pages
this.sendPageNo()
this.changePage = ''
} else {
this.pageNo = id * 1
this.sendPageNo()
this.changePage = ''
}
}else{
this.pageNo=1
this.sendPageNo()
this.changePage = ''
}
},
minus() {
if (this.pageNo > 1) {
this.pageNo--
this.sendPageNo()
}
},
add () {
if (this.pageNo < this.pages) {
this.pageNo++
this.sendPageNo()
}
}
}
}
css部分
<style lang="scss">
.page {
width: 100%;
height: 50px;
text-align: center;
color: #888;
margin: 18px auto 0;
}
.pagelist {
font-size: 0;
height: 25px;
a {
display: inline-block;
font-size: 11px;
vertical-align: middle;
min-width: 23px;
height: 23px;
line-height: 21px;
margin: 0 3px;
}
span {
display: inline-block;
font-size: 11px;
line-height: 23px;
margin: 0 3px;
vertical-align: middle;
}
.jump {
border: 1px solid #d9d9d9;
border-radius: 2px;
cursor: pointer;
color: rgba(0, 0, 0, .65);
.iconfont {
font-size: 10px;
text-align: center;
line-height: 22px;
color: rgba(0, 0, 0, .65);
}
&:hover {
color: #fff;
background: #1890FF;
border-color: #1890FF;
.iconfont {
color: #FFF;
}
}
&.disabled {
i {
color: rgba(0, 0, 0, .3);
}
&:hover {
background: #fff;
border: 1px solid #d9d9d9;
i {
color: rgba(0, 0, 0, .3);
}
}
}
}
.bgprimary {
pageNosor: default;
color: #fff;
background: #1890FF;
border-color: #1890FF;
}
.jumpinp {
width: 35px;
height: 23px;
font-size: 13px;
border: 1px solid #ccc;
border-radius: 2px;
text-align: center;
vertical-align: middle;
}
.ellipsis {
border: 1px solid #fff;
text-align: center;
}
.pages {
width: 60px;
height: 23px;
border-radius: 2px;
background-color: rgba(255, 255, 255, 1);
border: 0.72px solid rgba(217, 217, 217, 1);
}
.page-font {
display: none;
}
}
</style>