import PropTypes from '../_util/vue-types'; import BaseMixin from '../_util/BaseMixin'; import { hasProp, getComponent, splitAttrs, isValidElement } from '../_util/props-util'; import Pager from './Pager'; import Options from './Options'; import LOCALE from './locale/zh_CN'; import KEYCODE from './KeyCode'; import classNames from '../_util/classNames'; import { defineComponent } from 'vue'; import { cloneElement } from '../_util/vnode'; import firstNotUndefined from '../_util/firstNotUndefined'; import BaseInput from '../_util/BaseInput'; // 是否是正整数 function isInteger(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; } function defaultItemRender({ originalElement }) { return originalElement; } function calculatePage(p, state, props) { const pageSize = typeof p === 'undefined' ? state.statePageSize : p; return Math.floor((props.total - 1) / pageSize) + 1; } export default defineComponent({ compatConfig: { MODE: 3 }, name: 'Pagination', mixins: [BaseMixin], inheritAttrs: false, props: { disabled: { type: Boolean, default: undefined }, prefixCls: PropTypes.string.def('rc-pagination'), selectPrefixCls: PropTypes.string.def('rc-select'), current: Number, defaultCurrent: PropTypes.number.def(1), total: PropTypes.number.def(0), pageSize: Number, defaultPageSize: PropTypes.number.def(10), hideOnSinglePage: { type: Boolean, default: false }, showSizeChanger: { type: Boolean, default: undefined }, showLessItems: { type: Boolean, default: false }, // showSizeChange: PropTypes.func.def(noop), selectComponentClass: PropTypes.any, showPrevNextJumpers: { type: Boolean, default: true }, showQuickJumper: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]).def(false), showTitle: { type: Boolean, default: true }, pageSizeOptions: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), buildOptionText: Function, showTotal: Function, simple: { type: Boolean, default: undefined }, locale: PropTypes.object.def(LOCALE), itemRender: PropTypes.func.def(defaultItemRender), prevIcon: PropTypes.any, nextIcon: PropTypes.any, jumpPrevIcon: PropTypes.any, jumpNextIcon: PropTypes.any, totalBoundaryShowSizeChanger: PropTypes.number.def(50), }, data() { const props = this.$props; let current = firstNotUndefined([this.current, this.defaultCurrent]); const pageSize = firstNotUndefined([this.pageSize, this.defaultPageSize]); current = Math.min(current, calculatePage(pageSize, undefined, props)); return { stateCurrent: current, stateCurrentInputValue: current, statePageSize: pageSize, }; }, watch: { current(val) { this.setState({ stateCurrent: val, stateCurrentInputValue: val, }); }, pageSize(val) { const newState: any = {}; let current = this.stateCurrent; const newCurrent = calculatePage(val, this.$data, this.$props); 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(); } } }); }, total() { const newState: any = {}; const newCurrent = calculatePage(this.pageSize, this.$data, this.$props); if (hasProp(this, 'current')) { const current = Math.min(this.current, newCurrent); newState.stateCurrent = current; newState.stateCurrentInputValue = current; } else { let current = this.stateCurrent; if (current === 0 && newCurrent > 0) { current = 1; } else { current = Math.min(this.stateCurrent, newCurrent); } newState.stateCurrent = current; } this.setState(newState); }, }, methods: { getJumpPrevPage() { return Math.max(1, this.stateCurrent - (this.showLessItems ? 3 : 5)); }, getJumpNextPage() { return Math.min( calculatePage(undefined, this.$data, this.$props), this.stateCurrent + (this.showLessItems ? 3 : 5), ); }, getItemIcon(icon, label) { const { prefixCls } = this.$props; const iconNode = getComponent(this, icon, this.$props) || ( ); } else { gotoButton = ( {goButton} ); } gotoButton = (
  • {gotoButton}
  • ); } return ( ); } if (allPages <= 3 + pageBufferSize * 2) { const pagerProps = { locale, rootPrefixCls: prefixCls, showTitle, itemRender, onClick: this.handleChange, onKeypress: this.runIfEnter, }; if (!allPages) { pagerList.push( , ); } for (let i = 1; i <= allPages; i += 1) { const active = stateCurrent === i; pagerList.push(); } } else { const prevItemTitle = showLessItems ? locale.prev_3 : locale.prev_5; const nextItemTitle = showLessItems ? locale.next_3 : locale.next_5; if (showPrevNextJumpers) { jumpPrev = (
  • {itemRender({ page: this.getJumpPrevPage(), type: 'jump-prev', originalElement: this.getItemIcon('jumpPrevIcon', 'prev page'), })}
  • ); jumpNext = (
  • {itemRender({ page: this.getJumpNextPage(), type: 'jump-next', originalElement: this.getItemIcon('jumpNextIcon', 'next page'), })}
  • ); } lastPager = ( ); firstPager = ( ); 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 += 1) { const active = stateCurrent === i; pagerList.push( , ); } if (stateCurrent - 1 >= pageBufferSize * 2 && stateCurrent !== 1 + 2) { pagerList[0] = ( ); pagerList.unshift(jumpPrev); } if (allPages - stateCurrent >= pageBufferSize * 2 && stateCurrent !== allPages - 2) { pagerList[pagerList.length - 1] = ( ); pagerList.push(jumpNext); } if (left !== 1) { pagerList.unshift(firstPager); } if (right !== allPages) { pagerList.push(lastPager); } } let totalText = null; if (showTotal) { totalText = (
  • {showTotal(total, [ total === 0 ? 0 : (stateCurrent - 1) * statePageSize + 1, stateCurrent * statePageSize > total ? total : stateCurrent * statePageSize, ])}
  • ); } const prevDisabled = !hasPrev || !allPages; const nextDisabled = !hasNext || !allPages; const buildOptionText = this.buildOptionText || this.$slots.buildOptionText; return (
      {totalText}
    • {this.renderPrev(prevPage)}
    • {pagerList}
    • {this.renderNext(nextPage)}
    ); }, });