在寒假期间学习了vue这门新技术,于是这周就开始使用刚刚学的vue技术来写项目,借此来巩固新学习的知识,在写项目的过程中,我体会到了vue组件化的便捷之处,他可以将大的项目拆解为多个小项目,然后当再次需要使用到其中一部分小项目的时候,直接调用即可。再以前,当我遇到此类情况都是直接Ctrl+c和Ctrl+v的,那样操作虽然也很方便,但是当这一块的某一部分有问题或者是需要做出一些更新或改变的时候,会非常折磨人,要找代码找半天,但是使用vue之后,直接把对应的组件更改一下,所有用到这个组件的地方都会做出相应的改变,比以前方便了许多。
下面就是我使用vue写的分页按钮组件的html部分的代码,效果图如下
分为信息总条数,每页条数,分页按钮,跳转四大部分。这里的信息总条数是由使用了这一组件的父组件通过props传递进来的,每页条数也是由父组件传递进来的一个数组,在使用v-for遍历之后实现的select下拉框,以此来实现不同页面使用当前组件的时候允许选择的分页条数不同,分页按钮则是通过前两个属性,在本页面中使用计算属性来实现的。通过创建的一个名为index的变量,与v-if来实现选中按钮的高亮。当点击左右键的时候,控制index的增减,来切换页数。跳转则是在input框中使用了失去焦点事件与按键回落事件,之后获取里面的值,再来更改index的值。
<template>
<div class="dividePage">
<div class="dividePages">
<span class="totalNumber">共{{itemLength}}条</span>
<span class="pageSize">
<div class="select">
<div class="input">
<input type="text" readonly="readonly" autocomplete="off" :value="this.placeholder" class="inputInner">
<span class="suffix">
<span>
<i class="suffixI" @click="showDown()">
<img :class="{'down':upordown==1}" src="../assets/up.png">
</i>
</span>
</span>
</div>
<div class="dropDown" :class="{'hide':upordown==1}">
<div class="scrollbar">
<div class="wrap" style="margin-bottom: -17px; margin-right: -17px;">
<ul class="wrapList" v-for="(pagesize,index) in pagesizes"
:key="index">
<li class="dropdownItem" :class="{'selected': $store.state.select==index+1}" @click="choosethis(index)">
<span>{{pagesize}}条/页</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</span>
<button type="button" class="btnPrev" @click="prev()">
<i>
<img src="../assets/left.png">
</i>
</button>
<ul class="pager">
<li
v-for="index of page"
:key="index"
:class="{'active':isIndex==index}"
class="number"
@click="jump(index)"
>{{index+i}}</li>
</ul>
<button type="button" class="btnNext" @click="next()">
<i>
<img src="../assets/right.png">
</i>
</button>
<span class="jumpTo">
前往
<div class="jumpToPage">
<input
type="number"
autocomplete="off"
maxlength="1"
@keyup="jumpTo()"
ref="getValue"
oninput="if(value>9){value=9}else{value=value.replace(/[^\d]/g,'')}if(value.indexOf(0)==0){value=1}"
>
</div>
页
</span>
</div>
</div>
</template>
下面则是js部分的代码组件的名字是DividePage,通过props传递进来的三个值里,第一个是父组件的一个函数,通过它来把页数传递回去,执行查找请求,第二个是信息总条数,第三个是每页条数的数组形式,使用本组件的页面里,有的页面每条信息所占空间较大,页面在不影响用户视觉体验的情况下最多能容纳三条信息但是有的则最多可容纳十条信息,因此我设置了这个属性,用来传递每页条数的数组,兼容不同的页面。computed计算属性里的number则是计算得来的页面数量,通过这个来渲染按钮的数量,有的时候页面条数过多,会影响页面的美观程度,因此我设置了最多渲染四个按钮,但是这样一来通过index控制按钮高亮又会出现问题,所以我就加了一个i属性,初始为0,当总页数小于等于5的时候,i不变,在这个区间里,点击按钮跳转或者是点击左右键切换页面都是改变index值,但是当index=5的时候,将不再更改index的值,转而改变i的值,按钮内的数字原先是index,现在为index+1,当i大于0的时候,会给按钮里的数加上对应的值。
<script>
export default {
name: 'DividePage',
props:['changePage','itemLength','pagesizes'],
data() {
return {
upordown:1,
isIndex:1,
// select:1,
// number:5,
i:0,
placeholder:`${this.pagesizes[0]}条/页`,
}
},
computed:{
number(){
// console.log(this.$store.state.select)
var a = this.$store.state.select - 1
// console.log("page",this.pagesizes[a])
if(this.itemLength%(this.$store.state.select*this.pagesizes[a]) == 0){
return Math.floor(this.itemLength/(this.$store.state.select*this.pagesizes[a]))
}else{
return (Math.floor(this.itemLength/(this.$store.state.select*this.pagesizes[a]))+1)
}
},
page(){
if(this.number<=5){
return this.number
}else{
return 5
}
},
pageNumber(){
return this.isIndex + this.i
},
},
watch:{
pageNumber:{
immediate:true,
deep:true,
handler(newValue,oldValue){
console.log(newValue,oldValue)
this.do(newValue)
}
}
},
methods:{
do(value){
this.changePage(value)
},
showDown(){
if(this.upordown == 1){
this.upordown = 0
// console.log(this.upordown)
}else{
this.upordown = 1
// console.log(this.upordown)
}
},
choosethis(a){
// console.log(this.$store.state.select)
this.$store.dispatch('chooseit',a+1)
console.log(this.pagesizes)
console.log(this.pagesizes[0])
this.placeholder = `${this.pagesizes[a]}条/页`
// this.placeholder = `${a*5}条/页`
},
jump(a){
console.log(a)
this.isIndex = a
},
prev(){
if(this.isIndex + this.i > 1){
if(this.i>0){
this.i = this.i - 1
}else{
this.isIndex = this.isIndex - 1
}
}else{
alert("页数不能小于1!!!")
}
},
next(){
if(this.isIndex+this.i < this.number){
if(this.isIndex<5){
this.isIndex = this.isIndex + 1
}else{
this.i =this.i + 1
}
}else{
alert("后面没有信息了!!!")
}
},
jumpTo(){
if(this.$refs.getValue.value != '' && this.$refs.getValue.value<=this.number&&this.$refs.getValue.value>0){
if(this.$refs.getValue.value>5){
this.isIndex = 5
this.i = this.$refs.getValue.value - 5
}else{
this.isIndex = this.$refs.getValue.value
}
}else{
alert("请输入正确的格式")
}
},
}
}
</script>
最后就是我使用less写的style代码了,这里包括了下拉框样式,按钮样式,跳转样式等等样式。
<style lang="less" scoped>
.dividePage{
width: 100%;
height: 25px;
margin-bottom: 10px;
padding: 10px 20px!important;
.dividePages{
white-space: nowrap;
padding: 2px 5px;
color: #303133;
font-weight: 700;
float: right;
.totalNumber{
font-size: 16px;
margin-right: 5px;
}
.pageSize{
margin: 0 10px 0 0;
font-weight: 400;
color: #606266;
.select{
display: inline-block;
position: relative;
.input{
width: 100px;
margin: 0 5px;
display: block;
font-size: 12px;
.inputInner{
width: 100%;
border-radius: 3px;
font-size: 13px;
height: 28px;
line-height: 28px;
cursor: pointer;
border: 1px solid #dcdfe6;
color: #606266;
padding: 0 15px;
outline: none;
}
.suffix{
position: absolute;
height: 100%;
top: 0;
text-align: center;
color: #c0c4cc;
pointer-events: none;
span{
pointer-events: all;
}
.suffixI{
color: #c0c4cc;
font-size: 14px;
transition: all 0.6s;
cursor: pointer;
line-height: 28px;
width: 25px;
height: 100%;
text-align: center;
margin-left: -30px;
img{
margin-top: 8px;
width: 12px;
height: 12px;
transition: all 0.6s;
}
.down{
transform: rotateZ(-180deg);
}
}
}
}
.hide{
display:none;
min-width: 110px;
}
.dropDown{
position: absolute;
z-index: 1001;
border: 1px solid #dfe4ed;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
box-sizing: border-box;
margin: 5px 0 5px 5px;
.scrollbar{
overflow: hidden;
position: relative;
.wrap{
overflow: scroll;
height: 100%;
max-height: 274px;
.wrapList{
list-style: none;
padding: 6px 0;
margin: 0;
box-sizing: border-box;
.dropdownItem{
font-size: 14px;
padding: 0 20px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 34px;
box-sizing: border-box;
cursor: pointer;
}
.selected{
color: #1890ff;
font-weight: 700;
}
}
}
}
}
}
}
.btnPrev,.btnNext{
background-color: #f4f4f5;
color: #606266;
min-width: 30px;
min-height: 30px;
border-radius: 2px;
border: none;
cursor: pointer;
img{
margin-top: 3px;
width: 12px;
height: 12px;
}
}
.btnNext{
margin: 0 3px;
}
.pager{
user-select: none;
list-style: none;
display: inline-block;
vertical-align: top;
font-size: 0;
padding: 0;
margin: 0;
.active{
background-color: #1890ff !important;
color: #fff;
}
.number{
margin: 1px 3px 0 3px;
min-width: 30px;
border-radius: 2px;
padding: 0 4px;
background: #fff;
vertical-align: top;
display: inline-block;
font-size: 13px;
height: 28px;
line-height: 28px;
box-sizing: border-box;
text-align: center;
cursor: pointer;
}
}
.jumpTo{
margin-left: 24px;
margin-right: -12px;
font-weight: 400;
color: #606266;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
vertical-align: top;
box-sizing: border-box;
.jumpToPage{
width: 50px;
font-size: 14px;
line-height: 18px;
padding: 0 2px;
height: 28px;
text-align: center;
margin: 0 2px;
box-sizing: border-box;
border-radius: 3px;
display: inline;
input{
width: 50px;
height: 28px;
line-height: 36px;
padding: 0 3px;
text-align: center;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
color: #606266;
display: inline-block;
font-size: inherit;
outline: none;
}
}
}
}
}
</style>
最后则是父组件引入该分页组件的时候,需要传递的信息的格式
<DividePage :changePage="changePage" :itemLength="trendLength" :pagesizes="pagesizes"/>
在这里的changePage是写在父组件中的一个函数,里面调用了后端的接口,通过分页中返回的页数与每页信息条数,通过字符串拼接来把信息拼接在url上,然后再查询并返回相关信息,以此来实现分页功能。