-
Notifications
You must be signed in to change notification settings - Fork 352
/
Copy pathBasePagination.vue
134 lines (134 loc) · 3.44 KB
/
BasePagination.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<template>
<ul class="pagination" :class="[size && `pagination-${size}`, align && `justify-content-${align}`]">
<li class="page-item prev-page" :class="{disabled: value === 1}">
<a class="page-link" aria-label="Previous" @click="prevPage">
<span aria-hidden="true"><i class="fa fa-angle-left" aria-hidden="true"></i></span>
</a>
</li>
<li class="page-item" :class="{active: value === item}"
:key="item"
v-for="item in range(minPage, maxPage)">
<a class="page-link" @click="changePage(item)">{{item}}</a>
</li>
<li class="page-item next-page" :class="{disabled: value === totalPages}">
<a class="page-link" aria-label="Next" @click="nextPage">
<span aria-hidden="true"><i class="fa fa-angle-right" aria-hidden="true"></i></span>
</a>
</li>
</ul>
</template>
<script>
export default {
name: "base-pagination",
props: {
pageCount: {
type: Number,
default: 0,
description:
"Pagination page count. This should be specified in combination with perPage"
},
perPage: {
type: Number,
default: 10,
description:
"Pagination per page. Should be specified with total or pageCount"
},
total: {
type: Number,
default: 0,
description:
"Can be specified instead of pageCount. The page count in this case will be total/perPage"
},
value: {
type: Number,
default: 1,
description: "Pagination value"
},
size: {
type: String,
default: "",
description: "Pagination size"
},
align: {
type: String,
default: "",
description: "Pagination alignment (e.g center|start|end)"
}
},
computed: {
totalPages() {
if (this.pageCount > 0) return this.pageCount;
if (this.total > 0) {
return Math.ceil(this.total / this.perPage);
}
return 1;
},
pagesToDisplay() {
if (this.totalPages > 0 && this.totalPages < this.defaultPagesToDisplay) {
return this.totalPages;
}
return this.defaultPagesToDisplay;
},
minPage() {
if (this.value >= this.pagesToDisplay) {
const pagesToAdd = Math.floor(this.pagesToDisplay / 2);
const newMaxPage = pagesToAdd + this.value;
if (newMaxPage > this.totalPages) {
return this.totalPages - this.pagesToDisplay + 1;
}
return this.value - pagesToAdd;
} else {
return 1;
}
},
maxPage() {
if (this.value >= this.pagesToDisplay) {
const pagesToAdd = Math.floor(this.pagesToDisplay / 2);
const newMaxPage = pagesToAdd + this.value;
if (newMaxPage < this.totalPages) {
return newMaxPage;
} else {
return this.totalPages;
}
} else {
return this.pagesToDisplay;
}
}
},
data() {
return {
defaultPagesToDisplay: 5
};
},
methods: {
range(min, max) {
let arr = [];
for (let i = min; i <= max; i++) {
arr.push(i);
}
return arr;
},
changePage(item) {
this.$emit("input", item);
},
nextPage() {
if (this.value < this.totalPages) {
this.$emit("input", this.value + 1);
}
},
prevPage() {
if (this.value > 1) {
this.$emit("input", this.value - 1);
}
}
},
watch: {
perPage() {
this.$emit("input", 1);
},
total() {
this.$emit("input", 1);
}
}
};
</script>