经过前段时间webpack相关原理的浅析,从昨天开始学习到了Vue,由于本人做过开发,所以我不太喜欢把我当0基础的去看某些培训教育机构的学习视频,感觉有点不太适合我。所以就直接上手组件开发,边在开发的过程中,边学习、查阅官方文档。 怎么说呢,总的来说,感觉比纯看学习视频要记忆深刻 今天做了一个还算中等难度的组件——翻页组件,代码仅供参考,样式参考elementUI-pagination
实现效果
代码如下
<template>
<div class="pagination_container" v-show="totalPage > 1">
<button @click="onPageChange(current - 1)" class="page_button" :class="{ disabled: current === 1 }">
<Icon type="arrowLeft"></Icon>
</button>
<ul>
<template v-for="numberObject of numberObjects">
<li :key="numberObject.id" v-if="numberObject.type === 'number'" @click="onPageChange(numberObject.number)"
:class="{ selected: current === numberObject.number }">
{{ numberObject.number }}
</li>
<button
@click="onPageChange(current - 1)"
@mousemove="leftType = 'moreLeft'"
@mouseleave="leftType = 'ellipsis'"
:key="numberObject.id"
v-else-if="numberObject.type === 'more' && numberObject.arrow === 'left'"
class="page_button more">
<Icon :type="numberObject.arrow === 'left' ? leftType : rightType"></Icon>
</button>
<button
@click="onPageChange(current + 1)"
@mousemove="rightType = 'moreRight'"
@mouseleave="rightType = 'ellipsis'"
:key="numberObject.id"
v-else-if="numberObject.type === 'more' && numberObject.arrow === 'right'"
class="page_button more">
<Icon :type="rightType"></Icon>
</button>
</template>
</ul>
<button @click="onPageChange(current + 1)" class="page_button" :class="{ disabled: current === totalPage }">
<Icon type="arrowRight"></Icon>
</button>
</div>
</template>
<script>
import Icon from "../Icon"; // icon是我自己做的图标,图标素材来源于iconfont
export default {
name: "Pagination",
components: {
Icon
},
props: {
// 总数据量
total: {
type: Number,
require: true
},
// 当前页码
current: {
type: Number,
require: false,
default: 1
},
// 数字按钮页码显示的数量
pageCount: {
type: Number,
require: false,
default: 7,
validator: function (value) {
return value >= 7;
}
},
// 每页显示条目数
pageSize: {
type: Number,
require: false,
default: 10
}
},
data() {
return {
leftType: 'ellipsis',
rightType: 'ellipsis'
}
},
computed: {
totalPage() {
return Math.ceil(this.total / this.pageSize)
},
numberObjects() {
const restPageCount = this.pageCount - 2;
let min = this.current - Math.floor(restPageCount / 2);
min = min < 2 ? 2 : min;
let max = min + restPageCount - 1;
max = max > this.totalPage ? this.totalPage : max;
let leftDot = min > 2; // 计算出来显示的除1之外最小的数字大于2,显示左边的more
let rightDot = max < this.totalPage - 1; // 计算出来显示的除totalPage之外最大的数小于totalPage-1,显示右边的more
let numbers = [];
numbers.push({
type: 'number',
number: 1,
id: 1,
arrow: 'none'
});
if (leftDot) {
numbers.push({
type: 'more',
number: 0,
id: 2,
arrow: 'left',
});
}
for (let i = min; i <= max; i++) {
numbers.push({
type: 'number',
number: i,
id: i + 1,
arrow: 'none'
});
}
if (rightDot) {
numbers.push({
type: 'more',
number: 0,
id: max + 2,
arrow: 'right',
});
}
if (max !== this.totalPage) {
numbers.push({
type: 'number',
number: this.totalPage,
id: max + 3,
arrow: 'none',
});
}
return numbers
}
},
methods: {
onPageChange(number) {
if (number < 1 || number > this.totalPage) return;
if (number === this.current) return;
this.leftType = 'ellipsis'
this.rightType = 'ellipsis'
this.$emit('page-change', number)
}
},
}
</script>
<style lang="less" scoped>
@import "../../styles/variable.less";
.pagination_container {
ul {
margin: 0;
padding: 0;
display: inline-block;
}
.page_button, li {
margin: 0 5px;
background-color: @lightWhite;
color: @gray;
min-width: 30px;
border-radius: 2px;
cursor: pointer;
height: 28px;
line-height: 28px;
font-size: 13px;
box-sizing: border-box;
vertical-align: top;
border: none;
text-align: center;
user-select: none;
}
li {
list-style: none;
padding: 0 4px;
display: inline-block;
&.selected {
background: @primary;
color: @white;
}
&.more {
font-weight: bolder;
}
}
.page_button:hover,
li:not(.selected):hover {
color: @primary;
}
.page_button.disabled {
color: @disabled;
background-color: #fff;
cursor: not-allowed;
}
}
.iconfont {
font-size: 12px;
}
</style>