前言
分页组件也前端高频组件,但一般用在pc端,移动端出现比较少,因为按照移动端使用习惯在移动端通常会使用下拉加载刷新或者上拉加载刷新 这次编写的组件也是针对pc端。分页组件目的为了方便浏览通常将服务器响应回来的大量数据做分页
从实现方式上来说分页基本分为两种方式:
1.查询所有数据返回给客户,通过显示指定区间实现分页,这种方法一般是指JS分页
2.通过客户发送的请求,构造sql语句,查询表中的一段数据。
分页组件效果
屏幕录制2021-06-29 下午5.58.08.gif分页组件需求分析
1.总数据量,一般传入后端返回的数据总数字段
2.每页实际条数,传入自定数值
3.每页要显示条数,传入自定的数值,比如每页条数的是10条,在10条之间显示5条
4.总共多少页的计算公式是 总数据量
/每页要显示条数
5.点击下一页,上一页改变current
点击首页跳转第一页,点击尾页跳转到最尾一页,判断如果第一页和最尾一页设置禁止点击首页、下一页、上一页、尾页按钮
6.input框输入限制1 - 总数量的输入,设置数值跳转到当前页
7.currentCallBack
点击返回当前索引
8.传入color
可以自定喜欢的颜色
9.每页显示的条数计算,用vue的watch
来监听current值的变化 ,然后通过当前的current
计算出实际显示那几页出来,计算方式如下
watch: {
current(newVal) {
let temp = [],
max,
min = newVal - Math.floor(this.pageNum / 2)
if (min < 1) min = 1
max = min + this.pageNum - 1
if (max > this.pageTotalNum) max = this.pageTotalNum
for (let i = min; i <= max; i++) {
temp.push(i)
}
this.pageSizeNum = temp
}
},
props参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
page-total | 总数据 | Number | 100 |
page-num | 要显示页数 | Number | 10 |
page-size | 分页大小 | Number | 5 |
color | 传入的主题颜色 | Number | #409eff |
currentCallBack | 返回点击的当前索引值 | Events |
完整代码
<template>
<div class="_page_container">
<ul class="_pages _pages_1">
<li :class="['_home', setFristDisabled]" @click.prevent="setHomePageination">首页</li>
<li :class="['_prev_ _prev' ,setFristDisabled]" @click="prevPageination">上一页</li>
<li :class="['_pages_li_1',getCurrent(item)?'_active_1':'']"
:style="{backgroundColor : getCurrent(item) ? color : ''}"
:data-index="item"
v-for="(item) in pageSizeNum"
:key="item"
@click.prevent="switchPageination(item)"
>{{item}}
</li>
<li :class="['_next_ _next', setLastDisabled]"
@click.prevent="nextPageination">下一页
</li>
<li :class="['_last', setLastDisabled]"
@click="setLastPageination">尾页
</li>
</ul>
<div class="_jumper">
<span class="_count">共 {{pageTotalNum}} 页</span>
<span>前往</span>
<label>
<input class="_jumper_input"
type="number"
min="1"
:max="pageTotalNum"
@blur="jumpPageination($event)"
@keyup.enter="jumpPageination($event)"/>
</label>
<span>页</span>
</div>
</div>
</template>
<script>
export default {
name: 'pagination',
props: {
// 总数据
pageTotal: {
type: Number,
default: 100
},
// 实际分页大小
pageSize: {
type: Number,
default: 10
},
//显示页数
pageNum: {
type: Number,
default: 5
},
//自定义颜色
color: {
type: String,
default: '#409eff'
}
},
data() {
return {
current: 1,
pageSizeNum: Array.from({length: this.pageNum}, (_, index) => index + 1),
pageTotalNum: Math.ceil(this.pageTotal / this.pageSize)
}
},
computed: {
getCurrent() {
return (index) => {
return this.current === index
}
},
setFristDisabled() {
return this.current === 1 ? '_disabled_c _disabled' : ''
},
setLastDisabled() {
return this.current === this.pageTotalNum ? '_disabled_c _disabled' : ''
}
},
watch: {
current(newVal) {
let temp = [],
max,
min = newVal - Math.floor(this.pageNum / 2)
if (min < 1) min = 1
max = min + this.pageNum - 1
if (max > this.pageTotalNum) max = this.pageTotalNum
for (let i = min; i <= max; i++) {
temp.push(i)
}
this.pageSizeNum = temp
}
},
updated() {
this.$emit('currentCallBack', this.current - 1)
},
methods: {
switchPageination(index) {
this.current = index
},
nextPageination() {
if (this.current === this.pageTotalNum) {
this.current = this.pageTotalNum
}else {
this.current++
}
},
prevPageination() {
if (this.current === 1) {
this.current = 1
}else {
this.current--
}
},
setHomePageination() {
this.current = 1
},
setLastPageination() {
this.current = this.pageTotalNum
},
jumpPageination(ev) {
let value = Number(ev.currentTarget.value)
if (value < 1) value = 1
if (value > this.pageTotalNum) value = this.pageTotalNum
this.current = value
}
}
}
</script>
<style scoped>
._page_container {
height: 28px;
line-height: 28px;
text-align: center;
user-select: none;
}
._page_container input[type=number] {
-moz-appearance: textfield;
}
._page_container input[type=number]::-webkit-inner-spin-button,
._page_container input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
._page_container ._pages {
display: inline-block;
}
._page_container ._pages li {
display: inline-block;
list-style: none;
vertical-align: top;
color: #303133;
font-weight: bold;
min-width: 30px;
text-align: center;
margin: 0 5px;
border-radius: 2px;
cursor: pointer;
}
._page_container ._pages li:hover {
opacity: .6;
transition-duration: 500ms;
transition-timing-function: ease;
}
._page_container ._pages li:first-child, ._page_container ._pages li:last-child {
font-size: 14px;
}
._page_container ._pages ._prev, ._page_container ._pages ._next, ._page_container ._pages ._home, ._page_container ._pages ._last {
font-size: 12px;
font-weight: normal;
padding: 0 8px;
}
._page_container ._jumper {
display: inline-block;
color: #606266;
margin-left: 10px;
}
._page_container ._jumper ._count {
margin-right: 10px;
}
._page_container ._jumper ._jumper_input {
display: inline-block;
font-size: 14px;
color: #606266;
width: 50px;
height: 26px;
text-align: center;
margin: 0 5px;
padding: 3px;
border: 1px solid #dcdfe6;
border-radius: 4px;
background: none;
outline: none;
box-sizing: border-box;
}
._page_container ._jumper ._jumper_input:focus {
border-color: #409eff;
transition-duration: 500ms;
transition-timing-function: ease;
}
._pages_1 li {
background-color: #f4f4f5;
}
._active_1 {
color: #fff !important;
transition-duration: 500ms;
transition-timing-function: ease;
}
._active_2 {
color: #409eff !important;
}
._disabled {
cursor: not-allowed !important;
}
._disabled_c {
color: #c0c4cc !important;
}
</style>
最后
我要造轮子系列的分页组件也完成了,希望同学们有空余时间也多写写,大家一起学习、一起进步,共勉!!
npm
npm install nigo-vue-pagination
yarn
yarn add nigo-vue-pagination
github
git clone https://github.com/shinewen189/nigo-vue-pagination.git
我要造轮子系列文章
【2】.我要造轮子系列-常用的拖拽组件
网友评论