uni-pagination.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <template>
  2. <view class="uni-pagination">
  3. <view class="uni-pagination__btn" :class="currentIndex === 1 ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
  4. :hover-class="currentIndex === 1 ? '' : 'uni-pagination--hover'" :hover-start-time="20" :hover-stay-time="70"
  5. @click="clickLeft">
  6. <template v-if="showIcon===true || showIcon === 'true'">
  7. <uni-icons color="#000" size="20" type="arrowleft" />
  8. </template>
  9. <template v-else><text class="uni-pagination__child-btn">{{ prevText }}</text></template>
  10. </view>
  11. <view class="uni-pagination__num">
  12. <view class="uni-pagination__num-current">
  13. <text class="uni-pagination__num-current-text" style="color:#007aff">{{ currentIndex }}</text><text class="uni-pagination__num-current-text">/{{ maxPage || 0 }}</text>
  14. </view>
  15. </view>
  16. <view class="uni-pagination__btn" :class="currentIndex === maxPage ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
  17. :hover-class="currentIndex === maxPage ? '' : 'uni-pagination--hover'" :hover-start-time="20" :hover-stay-time="70"
  18. @click="clickRight">
  19. <template v-if="showIcon===true || showIcon === 'true'">
  20. <uni-icons color="#000" size="20" type="arrowright" />
  21. </template>
  22. <template v-else><text class="uni-pagination__child-btn">{{ nextText }}</text></template>
  23. </view>
  24. </view>
  25. </template>
  26. <script>
  27. import uniIcons from '../uni-icons/uni-icons.vue'
  28. /**
  29. * Pagination 分页器
  30. * @description 分页器组件,用于展示页码、请求数据等
  31. * @tutorial https://ext.dcloud.net.cn/plugin?id=32
  32. * @property {String} prevText 左侧按钮文字
  33. * @property {String} nextText 右侧按钮文字
  34. * @property {Number} current 当前页
  35. * @property {Number} total 数据总量
  36. * @property {Number} pageSize 每页数据量
  37. * @property {Number} showIcon = [true|false] 是否以 icon 形式展示按钮
  38. * @event {Function} change 点击页码按钮时触发 ,e={type,current} current为当前页,type值为:next/prev,表示点击的是上一页还是下一个
  39. */
  40. export default {
  41. name: 'UniPagination',
  42. components: {
  43. uniIcons
  44. },
  45. props: {
  46. prevText: {
  47. type: String,
  48. default: '上一页'
  49. },
  50. nextText: {
  51. type: String,
  52. default: '下一页'
  53. },
  54. current: {
  55. type: [Number, String],
  56. default: 1
  57. },
  58. total: { // 数据总量
  59. type: [Number, String],
  60. default: 0
  61. },
  62. pageSize: { // 每页数据量
  63. type: [Number, String],
  64. default: 10
  65. },
  66. showIcon: { // 是否以 icon 形式展示按钮
  67. type: [Boolean, String],
  68. default: false
  69. }
  70. },
  71. data() {
  72. return {
  73. currentIndex: 1
  74. }
  75. },
  76. computed: {
  77. maxPage() {
  78. let maxPage = 1
  79. let total = Number(this.total)
  80. let pageSize = Number(this.pageSize)
  81. if (total && pageSize) {
  82. maxPage = Math.ceil(total / pageSize)
  83. }
  84. return maxPage
  85. }
  86. },
  87. watch: {
  88. current(val) {
  89. this.currentIndex = +val
  90. }
  91. },
  92. created() {
  93. this.currentIndex = +this.current
  94. },
  95. methods: {
  96. clickLeft() {
  97. if (Number(this.currentIndex) === 1) {
  98. return
  99. }
  100. this.currentIndex -= 1
  101. this.change('prev')
  102. },
  103. clickRight() {
  104. if (Number(this.currentIndex) === this.maxPage) {
  105. return
  106. }
  107. this.currentIndex += 1
  108. this.change('next')
  109. },
  110. change(e) {
  111. this.$emit('change', {
  112. type: e,
  113. current: this.currentIndex
  114. })
  115. }
  116. }
  117. }
  118. </script>
  119. <style lang="scss" scoped>
  120. .uni-pagination {
  121. /* #ifndef APP-NVUE */
  122. display: flex;
  123. /* #endif */
  124. position: relative;
  125. overflow: hidden;
  126. flex-direction: row;
  127. justify-content: center;
  128. align-items: center;
  129. }
  130. .uni-pagination__btn {
  131. /* #ifndef APP-NVUE */
  132. display: flex;
  133. /* #endif */
  134. width: 60px;
  135. height: 30px;
  136. line-height: 30px;
  137. font-size: $uni-font-size-base;
  138. position: relative;
  139. background-color: $uni-bg-color-grey;
  140. flex-direction: row;
  141. justify-content: center;
  142. align-items: center;
  143. text-align: center;
  144. border-width: 1px;
  145. border-style: solid;
  146. border-color: $uni-border-color;
  147. }
  148. .uni-pagination__child-btn {
  149. /* #ifndef APP-NVUE */
  150. display: flex;
  151. /* #endif */
  152. font-size: $uni-font-size-base;
  153. position: relative;
  154. flex-direction: row;
  155. justify-content: center;
  156. align-items: center;
  157. text-align: center;
  158. }
  159. .uni-pagination__num {
  160. /* #ifndef APP-NVUE */
  161. display: flex;
  162. /* #endif */
  163. flex: 1;
  164. flex-direction: row;
  165. justify-content: center;
  166. align-items: center;
  167. height: 30px;
  168. line-height: 30px;
  169. font-size: $uni-font-size-base;
  170. color: $uni-text-color;
  171. }
  172. .uni-pagination__num-current {
  173. /* #ifndef APP-NVUE */
  174. display: flex;
  175. /* #endif */
  176. flex-direction: row;
  177. }
  178. .uni-pagination__num-current-text {
  179. font-size: 15px;
  180. }
  181. .uni-pagination--enabled {
  182. color: #333333;
  183. opacity: 1;
  184. }
  185. .uni-pagination--disabled {
  186. opacity: 0.3;
  187. }
  188. .uni-pagination--hover {
  189. color: rgba(0, 0, 0, .6);
  190. background-color: $uni-bg-color-hover;
  191. }
  192. </style>