cm-simple-swiper.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <view class="simple-swiper">
  3. <uni-swiper-dot :info="mapList" :current="current" mode="dot" :dotsStyles="dotsStyles">
  4. <swiper
  5. class="swiper"
  6. :style="{ height: swiperHeight + 'rpx' }"
  7. :indicator-dots="indicatorDots"
  8. :indicator-color="indicatorColor"
  9. :indicator-active-color="indicatorActiveColor"
  10. :autoplay="autoplay"
  11. :current="current"
  12. :interval="interval"
  13. :duration="duration"
  14. :circular="circular"
  15. :vertical="vertical"
  16. :previousMargin="previousMargin"
  17. :nextMargin="nextMargin"
  18. :skipHiddenItemLayout="skipHiddenItemLayout"
  19. :easingFunction="easingFunction"
  20. @change="onChange"
  21. @transition="onTransition"
  22. @animationfinish="onAnimationfinish"
  23. >
  24. <swiper-item v-for="(item, index1) in mapList" :key="index1">
  25. <view class="swiper__item" :style="layoutStyle">
  26. <template v-if="item.length">
  27. <view v-for="(data, index2) in item" class="grid" :key="index2">
  28. <slot :row="data" name="slide"></slot>
  29. </view>
  30. </template>
  31. <view v-else class="grid"><slot name="slide" :row="item"></slot></view>
  32. </view>
  33. </swiper-item>
  34. </swiper>
  35. </uni-swiper-dot>
  36. </view>
  37. </template>
  38. <script>
  39. import swiperProps from './mixins/swiper'
  40. export default {
  41. name: 'cm-simple-swiper',
  42. mixins: [swiperProps],
  43. props: {
  44. /* swiper数据 */
  45. data: {
  46. type: Array,
  47. default: () => []
  48. },
  49. // 行数
  50. rows: {
  51. type: Number,
  52. default: 1
  53. },
  54. // 列数
  55. columns: {
  56. type: Number,
  57. default: 1
  58. },
  59. swiperHeight: {
  60. type: Number,
  61. default: 350
  62. },
  63. gapX: {
  64. type: Number,
  65. default: 0
  66. },
  67. gapY: {
  68. type: Number,
  69. default: 0
  70. },
  71. padding: {
  72. type: String,
  73. default: '0'
  74. },
  75. autoFill: {
  76. type: Boolean,
  77. default: false
  78. }
  79. },
  80. computed: {
  81. // 真正渲染的列表
  82. mapList() {
  83. const result = this.formatSwiperList(this.data)
  84. return result
  85. },
  86. // 宽
  87. width() {
  88. return 100 / this.columns + '%'
  89. },
  90. dotsStyles() {
  91. return {
  92. width: 6,
  93. bottom: 8,
  94. color: 'background: rgba(255, 255, 255, 0.39)',
  95. backgroundColor: 'background: rgba(255, 255, 255, 0.39)',
  96. border: '0',
  97. selectedBackgroundColor: '#FF457B',
  98. selectedBorder: '#FF457B'
  99. }
  100. },
  101. layoutStyle() {
  102. return `
  103. display: grid;
  104. padding: ${this.padding};
  105. grid-template-columns: repeat(${this.columns}, 1fr);
  106. grid-template-rows: repeat(${this.rows}, 1fr);
  107. grid-column-gap: ${this.gapX}rpx;
  108. grid-row-gap: ${this.gapX}rpx;
  109. `
  110. }
  111. },
  112. methods: {
  113. // 处理轮播图数据列表
  114. formatSwiperList(list = []) {
  115. const result = []
  116. const count = this.rows * this.columns
  117. // 一屏仅有一个时
  118. if (count === 1) {
  119. return list
  120. }
  121. let start = 0
  122. // 一屏多个时
  123. while (list.length > 0) {
  124. if (start >= list.length) {
  125. break
  126. }
  127. const slice = list.slice(start, start + count)
  128. if (slice.length < count && this.autoFill) {
  129. slice.push(...this.fullArray(count - slice.length))
  130. }
  131. result.push(slice)
  132. start += count
  133. }
  134. return result
  135. },
  136. // 补全
  137. fullArray(count) {
  138. return this.data.slice(0, count)
  139. }
  140. }
  141. }
  142. </script>
  143. <style lang="scss" scoped>
  144. .grid {
  145. display: flex;
  146. justify-content: center;
  147. }
  148. </style>