paging.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <div class="layer" v-if="max>=1">
  3. <div class="number">
  4. <template v-if="currMin > min">
  5. <span @click="current = min">{{ min }}</span>
  6. <span v-if="currMin - 1 > min">…</span>
  7. </template>
  8. <span
  9. v-for="index in numbers"
  10. :key="index"
  11. :class="{ active: index === current }"
  12. @click="current = index"
  13. >
  14. {{ index }}
  15. </span>
  16. <template v-if="currMax < max">
  17. <span v-if="currMax + 1 < max">…</span>
  18. <span @click="current = max">{{ max }}</span>
  19. </template>
  20. <span v-if="current < max" class="next" @click="current = current + 1"></span>
  21. </div>
  22. </div>
  23. </template>
  24. <script>
  25. export default {
  26. props: ["paging"],
  27. data() {
  28. return {
  29. ...this.paging,
  30. };
  31. },
  32. computed: {
  33. min() {
  34. return 1;
  35. },
  36. max() {
  37. return Math.ceil(this.total / this.pageSize);
  38. },
  39. routineMin() {
  40. return this.current - Math.ceil(this.showSize / 2);
  41. },
  42. routineMax() {
  43. return this.current + Math.floor(this.showSize / 2);
  44. },
  45. currMin() {
  46. let c = this.max - this.routineMax;
  47. if (this.routineMin <= this.min) {
  48. return this.min;
  49. } else if (c >= 0) {
  50. return this.routineMin;
  51. } else if (this.routineMin + c <= this.min) {
  52. return this.min;
  53. } else {
  54. return this.routineMin + c;
  55. }
  56. },
  57. currMax() {
  58. let c = this.min - this.routineMin;
  59. if (this.routineMax >= this.max) {
  60. return this.max;
  61. } else if (c <= 0) {
  62. return this.routineMax;
  63. } else if (this.routineMax + c >= this.max) {
  64. return this.max;
  65. } else {
  66. return this.routineMax + c;
  67. }
  68. },
  69. numbers() {
  70. let total = this.currMax - this.currMin;
  71. let numbers = [];
  72. if (total === 0) {
  73. numbers.push(1);
  74. } else {
  75. for (let i = 0; i <= total; i++) {
  76. numbers.push(this.currMin + i);
  77. }
  78. }
  79. return numbers;
  80. },
  81. },
  82. watch: {
  83. current(val, old) {
  84. if (isNaN(this.current)) {
  85. return (this.current = old);
  86. } else if (this.current < this.min) {
  87. return (this.current = this.min);
  88. } else if (this.current > this.max) {
  89. return (this.current = this.max);
  90. }
  91. this.$emit("changeCurrent", this.current);
  92. },
  93. paging() {
  94. Object.keys(this.paging).forEach((k) => (this[k] = this.paging[k]));
  95. },
  96. "paging.total": function() {
  97. Object.keys(this.paging).forEach((k) => (this[k] = this.paging[k]));
  98. },
  99. },
  100. };
  101. </script>
  102. <style lang="less" scoped>
  103. @wh:32px;
  104. .layer {
  105. span {
  106. font-size: 16px;
  107. display: inline-block;
  108. vertical-align: middle;
  109. margin: 0 10px;
  110. color: #202020;
  111. font-weight: bold;
  112. width: @wh;
  113. height: @wh;
  114. text-align: center;
  115. line-height: @wh;
  116. &.active {
  117. color: #fff;
  118. background: #202020;
  119. }
  120. }
  121. .number span {
  122. margin: 0 5px;
  123. cursor: pointer;
  124. &:first-of-type{
  125. margin-left: 0;
  126. }
  127. }
  128. div {
  129. display: inline-block;
  130. }
  131. div input {
  132. background: none;
  133. border: 1px solid rgba(85, 85, 85, 1);
  134. width: 46px;
  135. height: 28px;
  136. border-radius: 2px;
  137. vertical-align: middle;
  138. text-align: center;
  139. color: #fff;
  140. }
  141. .next {
  142. position: relative;
  143. display: inline-flex;
  144. align-items: center;
  145. height: 22px;
  146. vertical-align: middle;
  147. &::before {
  148. content: "";
  149. background-color: #111;
  150. height: 2px;
  151. transition: 0.3s ease all;
  152. width: 8px;
  153. transform-origin: 0 0;
  154. }
  155. &::after {
  156. width: 0;
  157. transition: 0.2s ease all;
  158. content: "";
  159. height: 0;
  160. border-color: transparent transparent transparent #011111;
  161. border-style: solid;
  162. border-width: 5px 0 5px 8px;
  163. }
  164. &:hover {
  165. &::before {
  166. transform: scaleX(2);
  167. }
  168. &::after {
  169. transform: translateX(5px);
  170. }
  171. }
  172. }
  173. .layout .next-page-item:after {
  174. width: 0;
  175. height: 0;
  176. border-color: transparent transparent transparent #011111;
  177. border-style: solid;
  178. border-width: 5px 0 5px 8px;
  179. }
  180. }
  181. </style>