@@ -32,6 +32,7 @@ import Locale from './locale';
|
||||
import NavBar from './nav-bar';
|
||||
import NoticeBar from './notice-bar';
|
||||
import NumberKeyboard from './number-keyboard';
|
||||
import Pagination from './pagination';
|
||||
import Panel from './panel';
|
||||
import PasswordInput from './password-input';
|
||||
import Picker from './picker';
|
||||
@@ -92,6 +93,7 @@ const components = [
|
||||
NavBar,
|
||||
NoticeBar,
|
||||
NumberKeyboard,
|
||||
Pagination,
|
||||
Panel,
|
||||
PasswordInput,
|
||||
Picker,
|
||||
@@ -166,6 +168,7 @@ export {
|
||||
NavBar,
|
||||
NoticeBar,
|
||||
NumberKeyboard,
|
||||
Pagination,
|
||||
Panel,
|
||||
PasswordInput,
|
||||
Picker,
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<ul :class="['van-pagination', { 'van-pagination-simple': !isMultiMode }]">
|
||||
<li
|
||||
:class="[{ 'van-pagination--disabled': isNoPrevious } , 'van-pagination__item', 'van-pagination__prev', 'van-hairline']"
|
||||
@click="selectPage(currentPage - 1, $event)"
|
||||
>
|
||||
{{ previousText }}
|
||||
</li>
|
||||
<li
|
||||
v-if="isMultiMode"
|
||||
v-for="(page, index) in pages"
|
||||
:key="index"
|
||||
:class="[{ 'van-pagination--active': page.active }, 'van-pagination__item', 'van-pagination__page', 'van-hairline']"
|
||||
@click="selectPage(page.number, $event)"
|
||||
>
|
||||
{{ page.text }}
|
||||
</li>
|
||||
<li v-if="!isMultiMode" class="van-pagination__page-desc">
|
||||
<slot name="pageDesc">{{ pageDesc }}</slot>
|
||||
</li>
|
||||
<li
|
||||
:class="[{ 'van-pagination--disabled': isNoNext }, 'van-pagination__item', 'van-pagination__next', 'van-hairline']"
|
||||
@click="selectPage(currentPage + 1, $event)"
|
||||
>
|
||||
{{ nextText }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'van-pagination',
|
||||
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'multi'
|
||||
},
|
||||
forceEllipses: Boolean,
|
||||
itemsPerPage: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
showPageSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
validator: value => typeof value === 'number' && value >= 1
|
||||
},
|
||||
/* vModel { currentPage: 1, numPages: 10 } */
|
||||
value: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator: function(value) {
|
||||
return (
|
||||
value &&
|
||||
value.currentPage != undefined &&
|
||||
typeof value.currentPage === 'number'
|
||||
);
|
||||
}
|
||||
},
|
||||
previousText: {
|
||||
type: String,
|
||||
default: 'Previous'
|
||||
},
|
||||
nextText: {
|
||||
type: String,
|
||||
default: 'Next'
|
||||
},
|
||||
totalItems: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
const currentPage = this.value.currentPage !== undefined ? this.value.currentPage : 1;
|
||||
let totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil(this.totalItems / this.itemsPerPage);
|
||||
totalPages = Math.max(totalPages, 1);
|
||||
|
||||
return { currentPage, totalPages };
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMultiMode() {
|
||||
return this.mode === 'multi';
|
||||
},
|
||||
|
||||
isNoPrevious() {
|
||||
return this.value.currentPage === 1;
|
||||
},
|
||||
|
||||
isNoNext() {
|
||||
return this.value.currentPage === this.totalPages;
|
||||
},
|
||||
|
||||
pages() {
|
||||
const pages = [];
|
||||
|
||||
if (this.currentPage <= 0 || this.currentPage > this.totalPages) {
|
||||
return pages;
|
||||
}
|
||||
|
||||
// Default page limits
|
||||
let startPage = 1,
|
||||
endPage = this.totalPages;
|
||||
const isMaxSized = this.showPageSize !== undefined && this.showPageSize < this.totalPages;
|
||||
|
||||
// recompute if showPageSize
|
||||
if (isMaxSized) {
|
||||
// Current page is displayed in the middle of the visible ones
|
||||
startPage = Math.max(
|
||||
this.currentPage - Math.floor(this.showPageSize / 2),
|
||||
1
|
||||
);
|
||||
endPage = startPage + this.showPageSize - 1;
|
||||
|
||||
// Adjust if limit is exceeded
|
||||
if (endPage > this.totalPages) {
|
||||
endPage = this.totalPages;
|
||||
startPage = endPage - this.showPageSize + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Add page number links
|
||||
for (let number = startPage; number <= endPage; number++) {
|
||||
let page = this.makePage(number, number, number === this.currentPage);
|
||||
pages.push(page);
|
||||
}
|
||||
|
||||
// Add links to move between page sets
|
||||
if (isMaxSized && this.showPageSize > 0 && this.forceEllipses) {
|
||||
if (startPage > 1) {
|
||||
//need ellipsis for all options unless range is too close to beginning
|
||||
let previousPageSet = this.makePage(startPage - 1, '...', false);
|
||||
pages.unshift(previousPageSet);
|
||||
}
|
||||
|
||||
if (endPage < this.totalPages) {
|
||||
//need ellipsis for all options unless range is too close to end
|
||||
let nextPageSet = this.makePage(endPage + 1, '...', false);
|
||||
pages.push(nextPageSet);
|
||||
}
|
||||
}
|
||||
|
||||
return pages;
|
||||
},
|
||||
pageDesc() {
|
||||
return this.currentPage + '/' + this.totalPages;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 初始value值
|
||||
this.triggerInput();
|
||||
},
|
||||
|
||||
watch: {
|
||||
'value.currentPage'(value, oldValue) {
|
||||
this.currentPage = value;
|
||||
|
||||
this.$emit('change');
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
selectPage(page, evt) {
|
||||
if (this.currentPage !== page && page > 0 && page <= this.totalPages) {
|
||||
this.currentPage = page;
|
||||
}
|
||||
|
||||
this.triggerInput();
|
||||
},
|
||||
|
||||
triggerInput() {
|
||||
// Emit the new data to the parent.
|
||||
this.$emit('input', this.createDataForModel(this.currentPage, this.totalPages));
|
||||
},
|
||||
|
||||
makePage(number, text, active) {
|
||||
return { number, text, active };
|
||||
},
|
||||
|
||||
createDataForModel(currentPage, numPages) {
|
||||
let data = { currentPage, numPages };
|
||||
return data;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -18,6 +18,7 @@
|
||||
@import './notice-bar.css';
|
||||
@import './popup.css';
|
||||
@import './search.css';
|
||||
@import './pagination.css';
|
||||
@import './panel.css';
|
||||
@import './steps.css';
|
||||
@import './tag.css';
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
@import './common/var.css';
|
||||
|
||||
.van-pagination {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
|
||||
&__item {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
min-width: 36px;
|
||||
color: $blue;
|
||||
background-color: $white;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
|
||||
&:active {
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-width: 1px 0 1px 1px;
|
||||
}
|
||||
|
||||
&:last-child::after {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&__prev,
|
||||
&__next {
|
||||
&.van-pagination__item {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&__page {
|
||||
flex-grow: 0;
|
||||
|
||||
&.van-pagination--active {
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
|
||||
&.van-pagination__item {
|
||||
background-color: $background-color;
|
||||
color: $gray-darker;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
&__page-desc {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
color: $gray-darker;
|
||||
}
|
||||
}
|
||||
|
||||
.van-pagination-simple {
|
||||
|
||||
.van-pagination__prev,
|
||||
.van-pagination__next {
|
||||
|
||||
&.van-pagination__item::after {
|
||||
border-width: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user