fs-swiper.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <swiper
  3. :current="current"
  4. :indicator-dots="indicatorDots"
  5. :indicator-color="indicatorColor"
  6. :indicator-active-color="indicatorActiveColor"
  7. :autoplay="autoplay"
  8. :interval="interval"
  9. :duration="duration"
  10. :circular="circular"
  11. :vertical="vertical"
  12. :previous-margin="previousMargin"
  13. :next-margin="nextMargin"
  14. @change="handleChange"
  15. @transition="handleTransition"
  16. class="fs-swiper"
  17. :class="{ 'fs-swiper-card': mode === 'card', 'gutter-v': gutter }"
  18. :style="{ height: height }"
  19. >
  20. <template v-if="mode === 'card'">
  21. <swiper-item class="fs-swiper-item-box" v-for="(item, index) in list" :key="index" @click="handleClick(item)">
  22. <view class="fs-swiper-item" :class="{ 'card-cur': index === curIndex }">
  23. <fs-avatar shape="square" radius width="100%" height="100%" :src="item[keyMap.src]"></fs-avatar>
  24. <view class="fs-swiper-item-text line1" v-if="showTitle">{{ item[keyMap.title] }}</view>
  25. </view>
  26. </swiper-item>
  27. </template>
  28. <template v-else>
  29. <swiper-item class="fs-swiper-item-box" v-for="(item, index) in list" :key="index" @click="handleClick(item)">
  30. <view class="fs-swiper-item">
  31. <fs-avatar shape="square" width="100%" height="100%" :src="item[keyMap.src]"></fs-avatar>
  32. <view class="fs-swiper-item-text line1" v-if="showTitle">{{ item[keyMap.title] }}</view>
  33. </view>
  34. </swiper-item>
  35. </template>
  36. </swiper>
  37. </template>
  38. <script>
  39. /**
  40. * 轮播图组件
  41. * @description 轮播图组件
  42. * @property {Array} list 滚动列表
  43. * @property {Object} keyMap 属性映射
  44. * @property {Number} current 当前所在滑块的index
  45. * @property {Boolean} indicatorDots 是否显示指示器
  46. * @property {String} indicatorColor 指示器颜色
  47. * @property {String} indicatorActiveColor 指示器高亮颜色
  48. * @property {Boolean} autoplay 自动播放
  49. * @property {Boolean} vertical 竖直滚动
  50. * @property {Number} interval 播放间隔时长(单位ms)
  51. * @property {Number} duration 滚动动画持续时长(单位ms)
  52. * @property {String} previousMargin 前边距,可用于露出前一项的一小部分
  53. * @property {String} nextMargin 后边距,可用于露出后一项的一小部分
  54. * @property {String} height 滚动项高度
  55. * @property {String} mode 模式
  56. * @property {Boolean} gutter 是否有下边距
  57. * @property {Boolean} showTitle 是否显示标题
  58. * @event {Function} change change事件
  59. * @event {Function} transition transition事件
  60. */
  61. export default {
  62. name: 'fs-swiper'
  63. }
  64. </script>
  65. <script setup>
  66. import { ref } from 'vue'
  67. const props = defineProps({
  68. current: {
  69. type: Number,
  70. default: 0
  71. },
  72. indicatorDots: {
  73. type: Boolean,
  74. default: true
  75. },
  76. indicatorColor: {
  77. type: String,
  78. default: 'rgba(0, 0, 0, .3)'
  79. },
  80. indicatorActiveColor: {
  81. type: String,
  82. default: '#fff'
  83. },
  84. autoplay: {
  85. type: Boolean,
  86. default: true
  87. },
  88. circular: {
  89. type: Boolean,
  90. default: true
  91. },
  92. interval: {
  93. type: Number,
  94. default: 3000
  95. },
  96. duration: {
  97. type: Number,
  98. default: 1000
  99. },
  100. vertical: {
  101. type: Boolean,
  102. default: false
  103. },
  104. previousMargin: {
  105. type: String,
  106. default: '0'
  107. },
  108. nextMargin: {
  109. type: String,
  110. default: '0'
  111. },
  112. height: {
  113. type: String,
  114. default: '350rpx'
  115. },
  116. list: {
  117. type: Array,
  118. default() {
  119. return []
  120. }
  121. },
  122. keyMap: {
  123. type: Object,
  124. default() {
  125. return {
  126. src: 'src',
  127. title: 'title'
  128. }
  129. }
  130. },
  131. mode: {
  132. type: String
  133. },
  134. gutter: Boolean,
  135. showTitle: Boolean
  136. })
  137. const emits = defineEmits(['change', 'click', 'transition'])
  138. let curIndex = ref(0)
  139. const handleChange = e => {
  140. curIndex.value = e.detail.current
  141. emits('change', e)
  142. }
  143. const handleTransition = e => {
  144. emits('transition', e)
  145. }
  146. const handleClick = item => {
  147. emits('click', item)
  148. }
  149. </script>
  150. <style lang="scss" scoped>
  151. .fs-swiper {
  152. &-item {
  153. width: 100%;
  154. height: 100%;
  155. &-text {
  156. position: absolute;
  157. left: 0;
  158. right: 0;
  159. bottom: 0;
  160. background-color: rgba(0, 0, 0, 0.5);
  161. color: #fff;
  162. padding: 10rpx 20rpx;
  163. font-size: 14px;
  164. z-index: 10;
  165. }
  166. }
  167. }
  168. .fs-swiper-card {
  169. .fs-swiper-item-box {
  170. width: 610rpx !important;
  171. left: 70rpx;
  172. position: relative;
  173. }
  174. .fs-swiper-item {
  175. transform: scale(0.9);
  176. transition: all 0.2s ease-in 0s;
  177. overflow: hidden;
  178. }
  179. .card-cur {
  180. transform: scale(1);
  181. }
  182. }
  183. </style>