cm-simple-swiper.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. },
  76. computed: {
  77. // 真正渲染的列表
  78. mapList() {
  79. const result = this.formatSwiperList(this.data)
  80. console.log(result)
  81. return result
  82. },
  83. // 宽
  84. width() {
  85. return 100 / this.columns + '%'
  86. },
  87. dotsStyles() {
  88. return {
  89. width: 6,
  90. bottom: 8,
  91. color: 'background: rgba(255, 255, 255, 0.39)',
  92. backgroundColor: 'background: rgba(255, 255, 255, 0.39)',
  93. border: '0',
  94. selectedBackgroundColor: '#FF457B',
  95. selectedBorder: '#FF457B'
  96. }
  97. },
  98. layoutStyle() {
  99. return `
  100. display: grid;
  101. padding: ${this.padding};
  102. grid-template-columns: repeat(${this.columns}, 1fr);
  103. grid-template-rows: repeat(${this.rows}, 1fr);
  104. grid-column-gap: ${this.gapX}rpx;
  105. grid-row-gap: ${this.gapX}rpx;
  106. `
  107. }
  108. },
  109. methods: {
  110. // 处理轮播图数据列表
  111. formatSwiperList(list = []) {
  112. const result = []
  113. const count = this.rows * this.columns
  114. // 一屏仅有一个时
  115. if (count === 1) {
  116. return list
  117. }
  118. let start = 0
  119. // 一屏多个时
  120. while (list.length > 0) {
  121. if (start >= list.length) {
  122. break
  123. }
  124. const slice = list.slice(start, start + count)
  125. if (slice.length < count) {
  126. slice.push(...this.fullArray(count - slice.length))
  127. }
  128. result.push(slice)
  129. start += count
  130. }
  131. return result
  132. },
  133. // 补全
  134. fullArray(count) {
  135. return this.data.slice(0, count)
  136. }
  137. }
  138. }
  139. </script>
  140. <style lang="scss" scoped>
  141. .grid {
  142. display: flex;
  143. justify-content: center;
  144. }
  145. </style>