first
This commit is contained in:
8
packages/pagination/index.js
Normal file
8
packages/pagination/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import Pagination from './src/pagination';
|
||||
|
||||
/* istanbul ignore next */
|
||||
Pagination.install = function(Vue) {
|
||||
Vue.component(Pagination.name, Pagination);
|
||||
};
|
||||
|
||||
export default Pagination;
|
163
packages/pagination/src/pager.vue
Normal file
163
packages/pagination/src/pager.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<ul @click="onPagerClick" class="el-pager">
|
||||
<li
|
||||
:class="{ active: currentPage === 1, disabled }"
|
||||
v-if="pageCount > 0"
|
||||
class="number">1</li>
|
||||
<li
|
||||
class="el-icon more btn-quickprev"
|
||||
:class="[quickprevIconClass, { disabled }]"
|
||||
v-if="showPrevMore"
|
||||
@mouseenter="onMouseenter('left')"
|
||||
@mouseleave="quickprevIconClass = 'el-icon-more'">
|
||||
</li>
|
||||
<li
|
||||
v-for="pager in pagers"
|
||||
:key="pager"
|
||||
:class="{ active: currentPage === pager, disabled }"
|
||||
class="number">{{ pager }}</li>
|
||||
<li
|
||||
class="el-icon more btn-quicknext"
|
||||
:class="[quicknextIconClass, { disabled }]"
|
||||
v-if="showNextMore"
|
||||
@mouseenter="onMouseenter('right')"
|
||||
@mouseleave="quicknextIconClass = 'el-icon-more'">
|
||||
</li>
|
||||
<li
|
||||
:class="{ active: currentPage === pageCount, disabled }"
|
||||
class="number"
|
||||
v-if="pageCount > 1">{{ pageCount }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script type="text/babel">
|
||||
export default {
|
||||
name: 'ElPager',
|
||||
|
||||
props: {
|
||||
currentPage: Number,
|
||||
|
||||
pageCount: Number,
|
||||
|
||||
pagerCount: Number,
|
||||
|
||||
disabled: Boolean
|
||||
},
|
||||
|
||||
watch: {
|
||||
showPrevMore(val) {
|
||||
if (!val) this.quickprevIconClass = 'el-icon-more';
|
||||
},
|
||||
|
||||
showNextMore(val) {
|
||||
if (!val) this.quicknextIconClass = 'el-icon-more';
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onPagerClick(event) {
|
||||
const target = event.target;
|
||||
if (target.tagName === 'UL' || this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newPage = Number(event.target.textContent);
|
||||
const pageCount = this.pageCount;
|
||||
const currentPage = this.currentPage;
|
||||
const pagerCountOffset = this.pagerCount - 2;
|
||||
|
||||
if (target.className.indexOf('more') !== -1) {
|
||||
if (target.className.indexOf('quickprev') !== -1) {
|
||||
newPage = currentPage - pagerCountOffset;
|
||||
} else if (target.className.indexOf('quicknext') !== -1) {
|
||||
newPage = currentPage + pagerCountOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!isNaN(newPage)) {
|
||||
if (newPage < 1) {
|
||||
newPage = 1;
|
||||
}
|
||||
|
||||
if (newPage > pageCount) {
|
||||
newPage = pageCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (newPage !== currentPage) {
|
||||
this.$emit('change', newPage);
|
||||
}
|
||||
},
|
||||
|
||||
onMouseenter(direction) {
|
||||
if (this.disabled) return;
|
||||
if (direction === 'left') {
|
||||
this.quickprevIconClass = 'el-icon-d-arrow-left';
|
||||
} else {
|
||||
this.quicknextIconClass = 'el-icon-d-arrow-right';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
pagers() {
|
||||
const pagerCount = this.pagerCount;
|
||||
const halfPagerCount = (pagerCount - 1) / 2;
|
||||
|
||||
const currentPage = Number(this.currentPage);
|
||||
const pageCount = Number(this.pageCount);
|
||||
|
||||
let showPrevMore = false;
|
||||
let showNextMore = false;
|
||||
|
||||
if (pageCount > pagerCount) {
|
||||
if (currentPage > pagerCount - halfPagerCount) {
|
||||
showPrevMore = true;
|
||||
}
|
||||
|
||||
if (currentPage < pageCount - halfPagerCount) {
|
||||
showNextMore = true;
|
||||
}
|
||||
}
|
||||
|
||||
const array = [];
|
||||
|
||||
if (showPrevMore && !showNextMore) {
|
||||
const startPage = pageCount - (pagerCount - 2);
|
||||
for (let i = startPage; i < pageCount; i++) {
|
||||
array.push(i);
|
||||
}
|
||||
} else if (!showPrevMore && showNextMore) {
|
||||
for (let i = 2; i < pagerCount; i++) {
|
||||
array.push(i);
|
||||
}
|
||||
} else if (showPrevMore && showNextMore) {
|
||||
const offset = Math.floor(pagerCount / 2) - 1;
|
||||
for (let i = currentPage - offset ; i <= currentPage + offset; i++) {
|
||||
array.push(i);
|
||||
}
|
||||
} else {
|
||||
for (let i = 2; i < pageCount; i++) {
|
||||
array.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
this.showPrevMore = showPrevMore;
|
||||
this.showNextMore = showNextMore;
|
||||
|
||||
return array;
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
current: null,
|
||||
showPrevMore: false,
|
||||
showNextMore: false,
|
||||
quicknextIconClass: 'el-icon-more',
|
||||
quickprevIconClass: 'el-icon-more'
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
386
packages/pagination/src/pagination.js
Normal file
386
packages/pagination/src/pagination.js
Normal file
@@ -0,0 +1,386 @@
|
||||
import Pager from './pager.vue';
|
||||
import ElSelect from 'element-ui/packages/select';
|
||||
import ElOption from 'element-ui/packages/option';
|
||||
import ElInput from 'element-ui/packages/input';
|
||||
import Locale from 'element-ui/src/mixins/locale';
|
||||
import { valueEquals } from 'element-ui/src/utils/util';
|
||||
|
||||
export default {
|
||||
name: 'ElPagination',
|
||||
|
||||
props: {
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
|
||||
small: Boolean,
|
||||
|
||||
total: Number,
|
||||
|
||||
pageCount: Number,
|
||||
|
||||
pagerCount: {
|
||||
type: Number,
|
||||
validator(value) {
|
||||
return (value | 0) === value && value > 4 && value < 22 && (value % 2) === 1;
|
||||
},
|
||||
default: 7
|
||||
},
|
||||
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
|
||||
layout: {
|
||||
default: 'prev, pager, next, jumper, ->, total'
|
||||
},
|
||||
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 40, 50, 100];
|
||||
}
|
||||
},
|
||||
|
||||
popperClass: String,
|
||||
|
||||
prevText: String,
|
||||
|
||||
nextText: String,
|
||||
|
||||
background: Boolean,
|
||||
|
||||
disabled: Boolean,
|
||||
|
||||
hideOnSinglePage: Boolean
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
internalCurrentPage: 1,
|
||||
internalPageSize: 0,
|
||||
lastEmittedPage: -1,
|
||||
userChangePageSize: false
|
||||
};
|
||||
},
|
||||
|
||||
render(h) {
|
||||
const layout = this.layout;
|
||||
if (!layout) return null;
|
||||
if (this.hideOnSinglePage && (!this.internalPageCount || this.internalPageCount === 1)) return null;
|
||||
|
||||
let template = <div class={['el-pagination', {
|
||||
'is-background': this.background,
|
||||
'el-pagination--small': this.small
|
||||
}] }></div>;
|
||||
const TEMPLATE_MAP = {
|
||||
prev: <prev></prev>,
|
||||
jumper: <jumper></jumper>,
|
||||
pager: <pager currentPage={ this.internalCurrentPage } pageCount={ this.internalPageCount } pagerCount={ this.pagerCount } on-change={ this.handleCurrentChange } disabled={ this.disabled }></pager>,
|
||||
next: <next></next>,
|
||||
sizes: <sizes pageSizes={ this.pageSizes }></sizes>,
|
||||
slot: <slot>{ this.$slots.default ? this.$slots.default : '' }</slot>,
|
||||
total: <total></total>
|
||||
};
|
||||
const components = layout.split(',').map((item) => item.trim());
|
||||
const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
|
||||
let haveRightWrapper = false;
|
||||
|
||||
template.children = template.children || [];
|
||||
rightWrapper.children = rightWrapper.children || [];
|
||||
components.forEach(compo => {
|
||||
if (compo === '->') {
|
||||
haveRightWrapper = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!haveRightWrapper) {
|
||||
template.children.push(TEMPLATE_MAP[compo]);
|
||||
} else {
|
||||
rightWrapper.children.push(TEMPLATE_MAP[compo]);
|
||||
}
|
||||
});
|
||||
|
||||
if (haveRightWrapper) {
|
||||
template.children.unshift(rightWrapper);
|
||||
}
|
||||
|
||||
return template;
|
||||
},
|
||||
|
||||
components: {
|
||||
Prev: {
|
||||
render(h) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class="btn-prev"
|
||||
disabled={ this.$parent.disabled || this.$parent.internalCurrentPage <= 1 }
|
||||
on-click={ this.$parent.prev }>
|
||||
{
|
||||
this.$parent.prevText
|
||||
? <span>{ this.$parent.prevText }</span>
|
||||
: <i class="el-icon el-icon-arrow-left"></i>
|
||||
}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Next: {
|
||||
render(h) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class="btn-next"
|
||||
disabled={ this.$parent.disabled || this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0 }
|
||||
on-click={ this.$parent.next }>
|
||||
{
|
||||
this.$parent.nextText
|
||||
? <span>{ this.$parent.nextText }</span>
|
||||
: <i class="el-icon el-icon-arrow-right"></i>
|
||||
}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Sizes: {
|
||||
mixins: [Locale],
|
||||
|
||||
props: {
|
||||
pageSizes: Array
|
||||
},
|
||||
|
||||
watch: {
|
||||
pageSizes: {
|
||||
immediate: true,
|
||||
handler(newVal, oldVal) {
|
||||
if (valueEquals(newVal, oldVal)) return;
|
||||
if (Array.isArray(newVal)) {
|
||||
this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1
|
||||
? this.$parent.pageSize
|
||||
: this.pageSizes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
return (
|
||||
<span class="el-pagination__sizes">
|
||||
<el-select
|
||||
value={ this.$parent.internalPageSize }
|
||||
popperClass={ this.$parent.popperClass || '' }
|
||||
size="mini"
|
||||
on-input={ this.handleChange }
|
||||
disabled={ this.$parent.disabled }>
|
||||
{
|
||||
this.pageSizes.map(item =>
|
||||
<el-option
|
||||
value={ item }
|
||||
label={ item + this.t('el.pagination.pagesize') }>
|
||||
</el-option>
|
||||
)
|
||||
}
|
||||
</el-select>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
||||
components: {
|
||||
ElSelect,
|
||||
ElOption
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
if (val !== this.$parent.internalPageSize) {
|
||||
this.$parent.internalPageSize = val = parseInt(val, 10);
|
||||
this.$parent.userChangePageSize = true;
|
||||
this.$parent.$emit('update:pageSize', val);
|
||||
this.$parent.$emit('size-change', val);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Jumper: {
|
||||
mixins: [Locale],
|
||||
|
||||
components: { ElInput },
|
||||
|
||||
data() {
|
||||
return {
|
||||
userInput: null
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$parent.internalCurrentPage'() {
|
||||
this.userInput = null;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleKeyup({ keyCode, target }) {
|
||||
// Chrome, Safari, Firefox triggers change event on Enter
|
||||
// Hack for IE: https://github.com/ElemeFE/element/issues/11710
|
||||
// Drop this method when we no longer supports IE
|
||||
if (keyCode === 13) {
|
||||
this.handleChange(target.value);
|
||||
}
|
||||
},
|
||||
handleInput(value) {
|
||||
this.userInput = value;
|
||||
},
|
||||
handleChange(value) {
|
||||
this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value);
|
||||
this.$parent.emitChange();
|
||||
this.userInput = null;
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
return (
|
||||
<span class="el-pagination__jump">
|
||||
{ this.t('el.pagination.goto') }
|
||||
<el-input
|
||||
class="el-pagination__editor is-in-pagination"
|
||||
min={ 1 }
|
||||
max={ this.$parent.internalPageCount }
|
||||
value={ this.userInput !== null ? this.userInput : this.$parent.internalCurrentPage }
|
||||
type="number"
|
||||
disabled={ this.$parent.disabled }
|
||||
nativeOnKeyup={ this.handleKeyup }
|
||||
onInput={ this.handleInput }
|
||||
onChange={ this.handleChange }/>
|
||||
{ this.t('el.pagination.pageClassifier') }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Total: {
|
||||
mixins: [Locale],
|
||||
|
||||
render(h) {
|
||||
return (
|
||||
typeof this.$parent.total === 'number'
|
||||
? <span class="el-pagination__total">{ this.t('el.pagination.total', { total: this.$parent.total }) }</span>
|
||||
: ''
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Pager
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleCurrentChange(val) {
|
||||
this.internalCurrentPage = this.getValidCurrentPage(val);
|
||||
this.userChangePageSize = true;
|
||||
this.emitChange();
|
||||
},
|
||||
|
||||
prev() {
|
||||
if (this.disabled) return;
|
||||
const newVal = this.internalCurrentPage - 1;
|
||||
this.internalCurrentPage = this.getValidCurrentPage(newVal);
|
||||
this.$emit('prev-click', this.internalCurrentPage);
|
||||
this.emitChange();
|
||||
},
|
||||
|
||||
next() {
|
||||
if (this.disabled) return;
|
||||
const newVal = this.internalCurrentPage + 1;
|
||||
this.internalCurrentPage = this.getValidCurrentPage(newVal);
|
||||
this.$emit('next-click', this.internalCurrentPage);
|
||||
this.emitChange();
|
||||
},
|
||||
|
||||
getValidCurrentPage(value) {
|
||||
value = parseInt(value, 10);
|
||||
|
||||
const havePageCount = typeof this.internalPageCount === 'number';
|
||||
|
||||
let resetValue;
|
||||
if (!havePageCount) {
|
||||
if (isNaN(value) || value < 1) resetValue = 1;
|
||||
} else {
|
||||
if (value < 1) {
|
||||
resetValue = 1;
|
||||
} else if (value > this.internalPageCount) {
|
||||
resetValue = this.internalPageCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (resetValue === undefined && isNaN(value)) {
|
||||
resetValue = 1;
|
||||
} else if (resetValue === 0) {
|
||||
resetValue = 1;
|
||||
}
|
||||
|
||||
return resetValue === undefined ? value : resetValue;
|
||||
},
|
||||
|
||||
emitChange() {
|
||||
this.$nextTick(() => {
|
||||
if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) {
|
||||
this.$emit('current-change', this.internalCurrentPage);
|
||||
this.lastEmittedPage = this.internalCurrentPage;
|
||||
this.userChangePageSize = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
internalPageCount() {
|
||||
if (typeof this.total === 'number') {
|
||||
return Math.max(1, Math.ceil(this.total / this.internalPageSize));
|
||||
} else if (typeof this.pageCount === 'number') {
|
||||
return Math.max(1, this.pageCount);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
currentPage: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.internalCurrentPage = this.getValidCurrentPage(val);
|
||||
}
|
||||
},
|
||||
|
||||
pageSize: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.internalPageSize = isNaN(val) ? 10 : val;
|
||||
}
|
||||
},
|
||||
|
||||
internalCurrentPage: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.$emit('update:currentPage', newVal);
|
||||
this.lastEmittedPage = -1;
|
||||
}
|
||||
},
|
||||
|
||||
internalPageCount(newVal) {
|
||||
/* istanbul ignore if */
|
||||
const oldPage = this.internalCurrentPage;
|
||||
if (newVal > 0 && oldPage === 0) {
|
||||
this.internalCurrentPage = 1;
|
||||
} else if (oldPage > newVal) {
|
||||
this.internalCurrentPage = newVal === 0 ? 1 : newVal;
|
||||
this.userChangePageSize && this.emitChange();
|
||||
}
|
||||
this.userChangePageSize = false;
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user