element/packages/pagination/src/pagination.js

346 lines
8.2 KiB
JavaScript

import Pager from './pager.vue';
import ElSelect from 'element-ui/packages/select';
import ElOption from 'element-ui/packages/option';
import Locale from 'element-ui/src/mixins/locale';
export default {
name: 'ElPagination',
props: {
pageSize: {
type: Number,
default: 10
},
small: Boolean,
total: Number,
pageCount: Number,
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
},
data() {
return {
internalCurrentPage: 1,
internalPageSize: 0
};
},
render(h) {
let template = <div class='el-pagination'></div>;
const layout = this.layout || '';
if (!layout) return;
const TEMPLATE_MAP = {
prev: <prev></prev>,
jumper: <jumper></jumper>,
pager: <pager currentPage={ this.internalCurrentPage } pageCount={ this.internalPageCount } on-change={ this.handleCurrentChange }></pager>,
next: <next></next>,
sizes: <sizes pageSizes={ this.pageSizes }></sizes>,
slot: <my-slot></my-slot>,
total: <total></total>
};
const components = layout.split(',').map((item) => item.trim());
const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
let haveRightWrapper = false;
if (this.small) {
template.data.class += ' el-pagination--small';
}
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: {
MySlot: {
render(h) {
return (
this.$parent.$slots.default
? this.$parent.$slots.default[0]
: ''
);
}
},
Prev: {
render(h) {
return (
<button
type="button"
class={['btn-prev', { disabled: this.$parent.internalCurrentPage <= 1 }]}
on-click={ this.$parent.prev }>
<i class="el-icon el-icon-arrow-left"></i>
</button>
);
}
},
Next: {
render(h) {
return (
<button
type="button"
class={[
'btn-next',
{ disabled: this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0 }
]}
on-click={ this.$parent.next }>
<i class="el-icon el-icon-arrow-right"></i>
</button>
);
}
},
Sizes: {
mixins: [Locale],
props: {
pageSizes: Array
},
watch: {
pageSizes: {
immediate: true,
handler(value) {
if (Array.isArray(value)) {
this.$parent.internalPageSize = value.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 }
on-input={ this.handleChange }>
{
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.$emit('size-change', val);
}
}
}
},
Jumper: {
mixins: [Locale],
data() {
return {
oldValue: null
};
},
methods: {
handleFocus(event) {
this.oldValue = event.target.value;
},
handleKeyUp(event) {
const key = event.key || '';
const keyCode = event.keyCode || '';
if ((key && key === 'Enter') || (keyCode && keyCode === 13)) {
this.handleChange({ target: event.target });
}
},
handleChange({ target }) {
this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(target.value);
this.oldValue = null;
}
},
render(h) {
return (
<span class="el-pagination__jump">
{ this.t('el.pagination.goto') }
<input
class="el-pagination__editor"
type="number"
min={ 1 }
max={ this.internalPageCount }
value={ this.$parent.internalCurrentPage }
domProps-value={ this.$parent.internalCurrentPage }
on-change={ this.handleChange }
on-focus={ this.handleFocus }
on-keyup={ this.handleKeyUp }
number/>
{ 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);
},
prev() {
const newVal = this.internalCurrentPage - 1;
this.internalCurrentPage = this.getValidCurrentPage(newVal);
},
next() {
const newVal = this.internalCurrentPage + 1;
this.internalCurrentPage = this.getValidCurrentPage(newVal);
},
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;
}
},
computed: {
internalPageCount() {
if (typeof this.total === 'number') {
return Math.ceil(this.total / this.internalPageSize);
} else if (typeof this.pageCount === 'number') {
return this.pageCount;
}
return null;
}
},
watch: {
currentPage: {
immediate: true,
handler(val) {
this.internalCurrentPage = val;
}
},
pageSize: {
immediate: true,
handler(val) {
this.internalPageSize = val;
}
},
internalCurrentPage(newVal, oldVal) {
newVal = parseInt(newVal, 10);
/* istanbul ignore if */
if (isNaN(newVal)) {
newVal = oldVal || 1;
} else {
newVal = this.getValidCurrentPage(newVal);
}
if (newVal !== undefined) {
this.$nextTick(() => {
this.internalCurrentPage = newVal;
if (oldVal !== newVal) {
this.$emit('update:currentPage', newVal);
this.$emit('current-change', this.internalCurrentPage);
}
});
} else {
this.$emit('update:currentPage', newVal);
this.$emit('current-change', this.internalCurrentPage);
}
},
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;
}
}
}
};