index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { use } from '../utils';
  2. const [sfc, bem, t] = use('pagination');
  3. function makePage(number, text, active) {
  4. return { number, text, active };
  5. }
  6. export default sfc({
  7. props: {
  8. value: Number,
  9. prevText: String,
  10. nextText: String,
  11. pageCount: Number,
  12. totalItems: Number,
  13. forceEllipses: Boolean,
  14. mode: {
  15. type: String,
  16. default: 'multi'
  17. },
  18. itemsPerPage: {
  19. type: Number,
  20. default: 10
  21. },
  22. showPageSize: {
  23. type: Number,
  24. default: 5
  25. }
  26. },
  27. computed: {
  28. count() {
  29. const count = this.pageCount || Math.ceil(this.totalItems / this.itemsPerPage);
  30. return Math.max(1, count);
  31. },
  32. pages() {
  33. const pages = [];
  34. const pageCount = this.count;
  35. if (this.mode !== 'multi') {
  36. return pages;
  37. }
  38. // Default page limits
  39. let startPage = 1;
  40. let endPage = pageCount;
  41. const isMaxSized = this.showPageSize !== undefined && this.showPageSize < pageCount;
  42. // recompute if showPageSize
  43. if (isMaxSized) {
  44. // Current page is displayed in the middle of the visible ones
  45. startPage = Math.max(this.value - Math.floor(this.showPageSize / 2), 1);
  46. endPage = startPage + this.showPageSize - 1;
  47. // Adjust if limit is exceeded
  48. if (endPage > pageCount) {
  49. endPage = pageCount;
  50. startPage = endPage - this.showPageSize + 1;
  51. }
  52. }
  53. // Add page number links
  54. for (let number = startPage; number <= endPage; number++) {
  55. const page = makePage(number, number, number === this.value);
  56. pages.push(page);
  57. }
  58. // Add links to move between page sets
  59. if (isMaxSized && this.showPageSize > 0 && this.forceEllipses) {
  60. if (startPage > 1) {
  61. const previousPageSet = makePage(startPage - 1, '...', false);
  62. pages.unshift(previousPageSet);
  63. }
  64. if (endPage < pageCount) {
  65. const nextPageSet = makePage(endPage + 1, '...', false);
  66. pages.push(nextPageSet);
  67. }
  68. }
  69. return pages;
  70. }
  71. },
  72. watch: {
  73. value: {
  74. handler(page) {
  75. this.select(page || this.value);
  76. },
  77. immediate: true
  78. }
  79. },
  80. methods: {
  81. select(page) {
  82. page = Math.min(this.count, Math.max(1, page));
  83. if (this.value !== page) {
  84. this.$emit('input', page);
  85. this.$emit('change', page);
  86. }
  87. }
  88. },
  89. render(h) {
  90. const { value } = this;
  91. const simple = this.mode !== 'multi';
  92. const onSelect = value => () => {
  93. this.select(value);
  94. };
  95. return (
  96. <ul class={bem({ simple })}>
  97. <li
  98. class={[bem('item', { disabled: value === 1 }), bem('prev'), 'van-hairline']}
  99. onClick={onSelect(value - 1)}
  100. >
  101. {this.prevText || t('prev')}
  102. </li>
  103. {this.pages.map(page => (
  104. <li
  105. class={[bem('item', { active: page.active }), bem('page'), 'van-hairline']}
  106. onClick={onSelect(page.number)}
  107. >
  108. {page.text}
  109. </li>
  110. ))}
  111. {simple && (
  112. <li class={bem('page-desc')}>{this.slots('pageDesc') || `${value}/${this.count}`}</li>
  113. )}
  114. <li
  115. class={[bem('item', { disabled: value === this.count }), bem('next'), 'van-hairline']}
  116. onClick={onSelect(value + 1)}
  117. >
  118. {this.nextText || t('next')}
  119. </li>
  120. </ul>
  121. );
  122. }
  123. });