ant-design-vue/components/vc-pagination/Pagination.jsx
tangjinzhou ff25efe185
update to antd3.8.3 (#159)
* refactor: align

* feat:  update align to 2.4.3

* feat: update trigger 2.5.4

* feat: update tooltip 3.7.2

* fix: align

* feat: update vc-calendar to 9.6.2

* feat: update vc-checkbox to 2.1.5

* feat: update vc-dialog to 7.1.8

* feat: update vc-from to 2.2.1

* feat: update vc-notification to 3.1.1

* test: update snapshots

* feat: update vc-tree to 1.12.6

* feat: update vc-table to 6.2.8

* feat: update vc-upload to 2.5.1

* feat: update vc-input-number to 4.0.12

* feat: update vc-tabs to 9.2.6

* refactor: vc-menu

* refactor: update vc-menu to 7.0.5

* style: remove unused

* feat: update pagination to 1.16.5

* feat: add vc-progress 2.2.5 tag

* feat: add vc-rate 2.4.0 tag

* feat: update vc-slider to 8.6.1

* fix: tooltip error

* style: delete conosle

* feat: update vc-steps to 3.1.1

* add vc-switch tag 1.6.0

* feat: update upload to 2.5.1

* fix: update vc-menu

* fix: update store

* fix: add ref dir

* fix: trigger mock shouldComponentUpdate

* fix: update vc-select

* revert: trigger lazyrenderbox

* fix: update vc-select

* fix: update vc-select

* fix: update vc-select

* fix: update vc-menu

* fix: update vc-slick ref

* update style to 3.8.2

* test: update snapshots

* update vc-select

* update util & affix

* feat: add drawer

* fix: support title add slot mode

* test: update affix test

* update alert

* update anchor

* update snapshots

* fix: doc and vc-drawer

* update select & auto-complete

* update back-top & grid

* feractor: avatar

* test: add drawer test

* update badge

* update button

* update card

* update divider

* feat: update vc-tabs to 9.3.6 and tabs

* add afterEnter callback

* update form

* fix: update drawer

* test: update snapshots

* update modal & notification

* test: update snapshots

* update message

* update locale-provider

* update dropdown

* update layout popconfirm popover

* update time-picker

* update menu

* update date-picker

* docs: update input docs

* update input

* update snapshots

* update table

* update test snapshots

* feat: update progress

* update checkbox

* feat: update spin

* update radio

* docs: slider steps timeline

* update list

* update transfer

* update collapse

* update cascader

* update upload
2018-09-05 21:28:54 +08:00

558 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import PropTypes from '../_util/vue-types'
import BaseMixin from '../_util/BaseMixin'
import { hasProp } from '../_util/props-util'
import Pager from './Pager'
import Options from './Options'
import LOCALE from './locale/zh_CN'
import KEYCODE from './KeyCode'
function noop () {
}
// 是否是正整数
function isInteger (value) {
return typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value
}
function defaultItemRender (page, type, element) {
return element
}
export default {
name: 'Pagination',
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string.def('rc-pagination'),
selectPrefixCls: PropTypes.string.def('rc-select'),
current: PropTypes.number,
defaultCurrent: PropTypes.number.def(1),
total: PropTypes.number.def(0),
pageSize: PropTypes.number,
defaultPageSize: PropTypes.number.def(10),
change: PropTypes.func.def(noop),
hideOnSinglePage: PropTypes.bool.def(false),
showSizeChanger: PropTypes.bool.def(false),
showLessItems: PropTypes.bool.def(false),
// showSizeChange: PropTypes.func.def(noop),
selectComponentClass: PropTypes.any,
showPrevNextJumpers: PropTypes.bool.def(true),
showQuickJumper: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).def(false),
showTitle: PropTypes.bool.def(true),
pageSizeOptions: PropTypes.arrayOf(PropTypes.string),
buildOptionText: PropTypes.func,
showTotal: PropTypes.func,
simple: PropTypes.bool,
locale: PropTypes.object.def(LOCALE),
itemRender: PropTypes.func.def(defaultItemRender),
},
model: {
prop: 'current',
event: 'change',
},
data () {
const hasOnChange = this.onChange !== noop
const hasCurrent = hasProp(this, 'current')
if (hasCurrent && !hasOnChange) {
console.warn('Warning: You provided a `current` prop to a Pagination component without an `onChange` handler. This will render a read-only component.'); // eslint-disable-line
}
let current = this.defaultCurrent
if (hasCurrent) {
current = this.current
}
let pageSize = this.defaultPageSize
if (hasProp(this, 'pageSize')) {
pageSize = this.pageSize
}
return {
stateCurrent: current,
stateCurrentInputValue: current,
statePageSize: pageSize,
}
},
watch: {
current (val) {
this.setState({
stateCurrent: val,
stateCurrentInputValue: val,
})
},
pageSize (val) {
const newState = {}
let current = this.stateCurrent
const newCurrent = this.calculatePage(val)
current = current > newCurrent ? newCurrent : current
if (!hasProp(this, 'current')) {
newState.stateCurrent = current
newState.stateCurrentInputValue = current
}
newState.statePageSize = val
this.setState(newState)
},
stateCurrent (val, oldValue) {
// When current page change, fix focused style of prev item
// A hacky solution of https://github.com/ant-design/ant-design/issues/8948
this.$nextTick(() => {
if (this.$refs.paginationNode) {
const lastCurrentNode = this.$refs.paginationNode.querySelector(
`.${this.prefixCls}-item-${oldValue}`
)
if (lastCurrentNode && document.activeElement === lastCurrentNode) {
lastCurrentNode.blur()
}
}
})
},
},
methods: {
isValid (page) {
return isInteger(page) && page >= 1 && page !== this.stateCurrent
},
calculatePage (p) {
let pageSize = p
if (typeof pageSize === 'undefined') {
pageSize = this.statePageSize
}
return Math.floor((this.total - 1) / pageSize) + 1
},
handleGoTO (event) {
if (event.keyCode === KEYCODE.ENTER || event.type === 'click') {
this.handleChange(this.stateCurrentInputValue)
}
},
prev () {
if (this.hasPrev()) {
this.handleChange(this.stateCurrent - 1)
}
},
next () {
if (this.hasNext()) {
this.handleChange(this.stateCurrent + 1)
}
},
hasPrev () {
return this.stateCurrent > 1
},
hasNext () {
return this.stateCurrent < this.calculatePage()
},
handleKeyDown (event) {
if (event.keyCode === KEYCODE.ARROW_UP || event.keyCode === KEYCODE.ARROW_DOWN) {
event.preventDefault()
}
},
handleKeyUp (event) {
const inputValue = event.target.value
const stateCurrentInputValue = this.stateCurrentInputValue
let value
if (inputValue === '') {
value = inputValue
} else if (isNaN(Number(inputValue))) {
value = stateCurrentInputValue
} else {
value = Number(inputValue)
}
if (value !== stateCurrentInputValue) {
this.setState({
stateCurrentInputValue: value,
})
}
if (event.keyCode === KEYCODE.ENTER) {
this.handleChange(value)
} else if (event.keyCode === KEYCODE.ARROW_UP) {
this.handleChange(value - 1)
} else if (event.keyCode === KEYCODE.ARROW_DOWN) {
this.handleChange(value + 1)
}
},
changePageSize (size) {
let current = this.stateCurrent
const newCurrent = this.calculatePage(size)
current = current > newCurrent ? newCurrent : current
// fix the issue:
// Once 'total' is 0, 'current' in 'onShowSizeChange' is 0, which is not correct.
if (newCurrent === 0) {
current = this.stateCurrent
}
if (typeof size === 'number') {
if (!hasProp(this, 'pageSize')) {
this.setState({
statePageSize: size,
})
}
if (!hasProp(this, 'current')) {
this.setState({
stateCurrent: current,
stateCurrentInputValue: current,
})
}
}
this.$emit('update:pageSize', size)
this.$emit('showSizeChange', current, size)
this.$emit('change', current, size)
},
handleChange (p) {
let page = p
if (this.isValid(page)) {
const allTotal = this.calculatePage()
if (page > allTotal) {
page = allTotal
}
if (!hasProp(this, 'current')) {
this.setState({
stateCurrent: page,
stateCurrentInputValue: page,
})
}
// this.$emit('input', page)
this.$emit('change', page, this.statePageSize)
return page
}
return this.stateCurrent
},
runIfEnter (event, callback, ...restParams) {
if (event.key === 'Enter' || event.charCode === 13) {
callback(...restParams)
}
},
runIfEnterPrev (event) {
this.runIfEnter(event, this.prev)
},
runIfEnterNext (event) {
this.runIfEnter(event, this.next)
},
runIfEnterJumpPrev (event) {
this.runIfEnter(event, this.jumpPrev)
},
runIfEnterJumpNext (event) {
this.runIfEnter(event, this.jumpNext)
},
getJumpPrevPage () {
return Math.max(1, this.stateCurrent - (this.showLessItems ? 3 : 5))
},
getJumpNextPage () {
return Math.min(this.calculatePage(), this.stateCurrent + (this.showLessItems ? 3 : 5))
},
jumpPrev () {
this.handleChange(this.getJumpPrevPage())
},
jumpNext () {
this.handleChange(this.getJumpNextPage())
},
},
render () {
// When hideOnSinglePage is true and there is only 1 page, hide the pager
if (this.hideOnSinglePage === true && this.total <= this.statePageSize) {
return null
}
const locale = this.locale
const prefixCls = this.prefixCls
const allPages = this.calculatePage()
const pagerList = []
let jumpPrev = null
let jumpNext = null
let firstPager = null
let lastPager = null
let gotoButton = null
const goButton = (this.showQuickJumper && this.showQuickJumper.goButton)
const pageBufferSize = this.showLessItems ? 1 : 2
const { stateCurrent, statePageSize } = this
const prevPage = stateCurrent - 1 > 0 ? stateCurrent - 1 : 0
const nextPage = stateCurrent + 1 < allPages ? stateCurrent + 1 : allPages
if (this.simple) {
if (goButton) {
if (typeof goButton === 'boolean') {
gotoButton = (
<button
type='button'
onClick={this.handleGoTO}
onKeyup={this.handleGoTO}
>
{locale.jump_to_confirm}
</button>
)
} else {
gotoButton = (
<span
onClick={this.handleGoTO}
onKeyup={this.handleGoTO}
>{goButton}</span>
)
}
gotoButton = (
<li
title={this.showTitle ? `${locale.jump_to}${this.stateCurrent}/${allPages}` : null}
class={`${prefixCls}-simple-pager`}
>
{gotoButton}
</li>
)
}
const hasPrev = this.hasPrev()
const hasNext = this.hasNext()
return (
<ul class={`${prefixCls} ${prefixCls}-simple`}>
<li
title={this.showTitle ? locale.prev_page : null}
onClick={this.prev}
tabIndex={hasPrev ? 0 : null}
onKeypress={this.runIfEnterPrev}
class={`${hasPrev ? '' : `${prefixCls}-disabled`} ${prefixCls}-prev`}
aria-disabled={!this.hasPrev()}
>
{this.itemRender(prevPage, 'prev', <a class={`${prefixCls}-item-link`} />)}
</li>
<li
title={this.showTitle ? `${stateCurrent}/${allPages}` : null}
class={`${prefixCls}-simple-pager`}
>
<input
type='text'
value={this.stateCurrentInputValue}
onKeydown={this.handleKeyDown}
onKeyup={this.handleKeyUp}
onInput={this.handleKeyUp}
size='3'
/>
<span class={`${prefixCls}-slash`}></span>
{allPages}
</li>
<li
title={this.showTitle ? locale.next_page : null}
onClick={this.next}
tabIndex={this.hasNext ? 0 : null}
onKeypress={this.runIfEnterNext}
class={`${hasNext ? '' : `${prefixCls}-disabled`} ${prefixCls}-next`}
aria-disabled={!this.hasNext()}
>
{this.itemRender(nextPage, 'next', <a class={`${prefixCls}-item-link`} />)}
</li>
{gotoButton}
</ul>
)
}
if (allPages <= 5 + pageBufferSize * 2) {
for (let i = 1; i <= allPages; i++) {
const active = stateCurrent === i
pagerList.push(
<Pager
locale={locale}
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={i}
page={i}
active={active}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
}
} else {
const prevItemTitle = this.showLessItems ? locale.prev_3 : locale.prev_5
const nextItemTitle = this.showLessItems ? locale.next_3 : locale.next_5
if (this.showPrevNextJumpers) {
jumpPrev = (
<li
title={this.showTitle ? prevItemTitle : null}
key='prev'
onClick={this.jumpPrev}
tabIndex='0'
onKeypress={this.runIfEnterJumpPrev}
class={`${prefixCls}-jump-prev`}
>
{this.itemRender(
this.getJumpPrevPage(), 'jump-prev', <a class={`${prefixCls}-item-link`} />
)}
</li>
)
jumpNext = (
<li
title={this.showTitle ? nextItemTitle : null}
key='next'
tabIndex='0'
onClick={this.jumpNext}
onKeypress={this.runIfEnterJumpNext}
class={`${prefixCls}-jump-next`}
>
{this.itemRender(
this.getJumpNextPage(), 'jump-next', <a class={`${prefixCls}-item-link`} />
)}
</li>
)
}
lastPager = (
<Pager
locale={locale}
last
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={allPages}
page={allPages}
active={false}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
firstPager = (
<Pager
locale={locale}
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={1}
page={1}
active={false}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
let left = Math.max(1, stateCurrent - pageBufferSize)
let right = Math.min(stateCurrent + pageBufferSize, allPages)
if (stateCurrent - 1 <= pageBufferSize) {
right = 1 + pageBufferSize * 2
}
if (allPages - stateCurrent <= pageBufferSize) {
left = allPages - pageBufferSize * 2
}
for (let i = left; i <= right; i++) {
const active = stateCurrent === i
pagerList.push(
<Pager
locale={locale}
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={i}
page={i}
active={active}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
}
if (stateCurrent - 1 >= pageBufferSize * 2 && stateCurrent !== 1 + 2) {
pagerList[0] = (
<Pager
locale={locale}
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={left}
page={left}
class={`${prefixCls}-item-after-jump-prev`}
active={false}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
pagerList.unshift(jumpPrev)
}
if (allPages - stateCurrent >= pageBufferSize * 2 && stateCurrent !== allPages - 2) {
pagerList[pagerList.length - 1] = (
<Pager
locale={locale}
rootPrefixCls={prefixCls}
onClick={this.handleChange}
onKeypress={this.runIfEnter}
key={right}
page={right}
class={`${prefixCls}-item-before-jump-next`}
active={false}
showTitle={this.showTitle}
itemRender={this.itemRender}
/>
)
pagerList.push(jumpNext)
}
if (left !== 1) {
pagerList.unshift(firstPager)
}
if (right !== allPages) {
pagerList.push(lastPager)
}
}
let totalText = null
if (this.showTotal) {
totalText = (
<li class={`${prefixCls}-total-text`}>
{this.showTotal(
this.total,
[
(stateCurrent - 1) * statePageSize + 1,
stateCurrent * statePageSize > this.total ? this.total : stateCurrent * statePageSize,
]
)}
</li>
)
}
const prevDisabled = !this.hasPrev()
const nextDisabled = !this.hasNext()
const buildOptionText = this.buildOptionText || this.$scopedSlots.buildOptionText
return (
<ul
class={`${prefixCls}`}
unselectable='unselectable'
ref='paginationNode'
>
{totalText}
<li
title={this.showTitle ? locale.prev_page : null}
onClick={this.prev}
tabIndex={prevDisabled ? null : 0}
onKeypress={this.runIfEnterPrev}
class={`${!prevDisabled ? '' : `${prefixCls}-disabled`} ${prefixCls}-prev`}
aria-disabled={prevDisabled}
>
{this.itemRender(prevPage, 'prev', <a class={`${prefixCls}-item-link`} />)}
</li>
{pagerList}
<li
title={this.showTitle ? locale.next_page : null}
onClick={this.next}
tabIndex={nextDisabled ? null : 0}
onKeypress={this.runIfEnterNext}
class={`${!nextDisabled ? '' : `${prefixCls}-disabled`} ${prefixCls}-next`}
aria-disabled={nextDisabled}
>
{this.itemRender(nextPage, 'next', <a class={`${prefixCls}-item-link`} />)}
</li>
<Options
locale={locale}
rootPrefixCls={prefixCls}
selectComponentClass={this.selectComponentClass}
selectPrefixCls={this.selectPrefixCls}
changeSize={this.showSizeChanger ? this.changePageSize : null}
current={stateCurrent}
pageSize={statePageSize}
pageSizeOptions={this.pageSizeOptions}
buildOptionText={buildOptionText || null}
quickGo={this.showQuickJumper ? this.handleChange : null}
goButton={goButton}
/>
</ul>
)
},
}