kui-vue
Version:
A high quality UI Toolkit built on Vue.js 2.0
248 lines (244 loc) • 7.61 kB
JSX
import { Select, Option } from '../select'
import { Input } from '../input'
import Icon from '../icon'
import { t } from '../locale';
import { ChevronUp, ChevronDoubleBack, Ellipsis, ChevronDoubleForward } from 'kui-icons'
export default {
name: "Page",
props: {
showSizer: Boolean,
showTotal: { type: Boolean, default: true },
showElevator: Boolean,
sizeData: { type: Array, default: () => [10, 15, 20, 30, 40] },
size: {
default: 'default',
validator(value) {
return ["small", "large", "default"].indexOf(value) >= 0;
}
},
total: { default: 0, type: Number },
pageSize: { default: 10, type: Number },
current: { default: 1, type: Number }
},
model: {
prop: 'current',
event: 'input'
},
data() {
return {
nextPageGroup: false,
prevPageGroup: false,
pageCount: 0,
page: this.current,
defaultPageSize: this.pageSize
}
},
watch: {
pageSize(v) {
this.defaultPageSize = v
this.resetPage()
},
current(v) {
this.page = v
this.resetPage()
},
total(v) {
this.resetPage()
}
},
mounted() {
this.pageCount = Math.ceil(this.total / this.defaultPageSize) || 1;
},
methods: {
resetPage() {
this.pageCount = Math.ceil(this.total / this.defaultPageSize) || 1;
if (this.page > this.pageCount) {
this.page = this.pageCount
this.$emit('input', this.page)
this.$emit('change', this.page)
}
},
renderPage() {
const groupCount = 7,
page = Number(this.page),
pageCount = Number(this.pageCount);
let showPrevMore = false;
let showNextMore = false;
if (pageCount > groupCount) {
if (page > groupCount - 3) { showPrevMore = true; }
if (page < pageCount - 3) { showNextMore = true; }
}
const array = [];
if (showPrevMore && !showNextMore) {
const startPage = pageCount - (groupCount - 2);
for (let i = startPage; i < pageCount; i++) {
array.push(i);
}
} else if (!showPrevMore && showNextMore) {
for (let i = 2; i < groupCount; i++) {
array.push(i);
}
} else if (showPrevMore && showNextMore) {
const offset = Math.floor(groupCount / 2) - 1;
for (let i = page - offset; i <= page + offset; i++) {
array.push(i);
}
} else {
for (let i = 2; i < pageCount; i++) {
array.push(i);
}
}
let child = array.map((p, i) => {
let prop = {
class: ['k-pager-item', { 'k-pager-item-active': page == p }],
key: i,
on: { click: e => this.toPage(p) }
}
return <li {...prop}><span>{p}</span></li>
})
if (showPrevMore) {
let p = {
class: 'k-pager-item k-pager-more',
on: {
mouseenter: () => this.prevPageGroup = true,
mouseleave: () => this.prevPageGroup = false,
click: () => this.toPage(this.page - 5)
}
}
const moreNode = <li {...p}><Icon strokeWidth={30} type={this.prevPageGroup ? ChevronDoubleBack : Ellipsis} /></li>;
child.unshift(moreNode)
}
if (showNextMore) {
let p = {
class: 'k-pager-item k-pager-more',
on: {
mouseenter: () => this.nextPageGroup = true,
mouseleave: () => this.nextPageGroup = false,
click: () => this.toPage(this.page + 5)
}
}
const moreNode = <li {...p}><Icon strokeWidth={30} type={this.nextPageGroup ? ChevronDoubleForward : Ellipsis} /></li>;
child.push(moreNode)
}
return child
},
prePage() {
if (this.page > 1) {
this.page--;
this.$emit('input', this.page)
this.$emit('change', this.page)
}
},
nextPage() {
if (this.page < this.pageCount) {
this.page++;
this.$emit('input', this.page)
this.$emit('change', this.page)
}
},
toPage(page) {
if (page == this.page) return;
if (page <= 1) {
page = 1
this.prevPageGroup = false
}
if (page >= this.pageCount) {
this.nextPageGroup = false
page = this.pageCount
}
this.page = page
this.$emit('input', page)
this.$emit('change', page)
},
changeSize({ value }) {
this.defaultPageSize = value
this.pageCount = Math.ceil(this.total / this.defaultPageSize) || 1;
if (this.page > this.pageCount) {
this.page = this.pageCount
this.$emit('input', page)
this.$emit('change', page)
}
this.$emit('page-size-change', { current: this.page, pageSize: value })
},
renderFirst() {
if (this.pageCount > 0) {
return <li class={["k-pager-item", { 'k-pager-item-active': this.page == 1 }]} onClick={e => this.toPage(1)} >
<span>1</span>
</li>
}
return null
},
renderLast() {
let { pageCount } = this
if (pageCount > 1) {
return <li class={['k-pager-item', { 'k-pager-item-active': this.page == pageCount }]} onClick={e => this.toPage(pageCount)} >
<span>{pageCount}</span>
</li>
}
return null
},
renderSize() {
let prop = {
props: {
value: this.defaultPageSize,
size: this.size,
options: this.sizeData.map(s => {
return { value: s, label: `${s}${t('k.page.pageSize')}` }
})
},
on: {
input: e => this.defaultPageSize = e,
change: this.changeSize
},
}
return (this.showSizer ? <div class="k-page-sizer"><Select {...prop} /></div > : null)
},
renderElvator() {
let { size } = this
let prop = {
class: 'k-page-options-elevator',
props: { size, value: this.page },
on: {
blur: e => {
let page = e.target.value;
let { pageCount } = this
if (page > pageCount) page = pageCount
if (page < 1) page = 1
if ((page >= 1 || page <= pageCount) && this.page != page) {
this.page = page
this.$emit('input', page)
this.$emit('change', page)
}
},
// change: e => this.page = e
}
}
return (
this.showElevator ?
<div class="k-page-options">
<span>{t('k.page.goto')}</span><Input {...prop} /><span>{t('k.page.page')}</span>
</div> : null
)
}
},
render() {
const classes = ["k-page", { ["k-page-sm"]: this.size == 'small' }],
preNode = <li class={['k-pager-item k-pager-prev', { 'k-pager-item-disabled': this.page == 1 }]} onClick={this.prePage}><Icon type={ChevronUp} /></li>,
nextNode = <li class={['k-pager-item k-pager-next', { 'k-pager-item-disabled': this.page == this.pageCount }]} onClick={this.nextPage}><Icon type={ChevronUp} /></li>,
totalNode = (this.showTotal ? <div class="k-page-number"><span>{t('k.page.total')} {this.total} {t('k.page.items')}</span></div> : null),
pagerNode = this.renderPage(),
sizeNode = this.renderSize(),
elvatorNode = this.renderElvator(),
firstNode = this.renderFirst(),
lastNode = this.renderLast()
return (
<div class={classes}>
{totalNode}
<ul class="k-pager">
{[preNode, firstNode, pagerNode, lastNode, nextNode,]}
</ul>
{[sizeNode, elvatorNode]}
</div>
)
}
}