SwiperBanner.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <view class="detail-banner" :style="{height:bannerH/3.75+'vw'}">
  3. <swiper :autoplay="autoPlay" :interval="4000" :duration="500" :circular="true" class="swiper-box"
  4. :previous-margin="previousNext" :next-margin="previousNext" :snap-to-edge="true" @change="swiperChange"
  5. v-if="bannerDetail.length">
  6. <block v-for="(item,index) in bannerDetail" :key="index">
  7. <swiper-item
  8. :class="[bannerType=='3D'?(index === cur?'swiper-bigger':'swiper-smaller'):'','swiper-item']">
  9. <image v-if="item.type === 1" mode="aspectFill" @tap.stop="chooseSwiper(item)" :lazy-load="true"
  10. :style="{borderRadius:radius/3.75+'vw'}"
  11. :class="[bannerType=='3D'?(index === cur?'image-bigger':'image-smaller'):'banner-image']"
  12. :src="(item[imgKey] ? item[imgKey].url : '') || (item ? item.url : '')" />
  13. <video v-if="item.type === 2 && index === cur" mode="aspectFill" @tap.stop="chooseSwiper(item)" :lazy-load="true"
  14. :style="{borderRadius:radius/3.75+'vw'}"
  15. :class="[bannerType=='3D'?(index === cur?'image-bigger':'image-smaller'):'banner-image']"
  16. :src="(item[imgKey] ? item[imgKey].url : '') || (item ? item.url : '')"></video>
  17. </swiper-item>
  18. </block>
  19. </swiper>
  20. <!--重置小圆点的样式 -->
  21. <view class="dots" v-if="indicatorDots">
  22. <view class="dots-bk" v-if="dotsType=='dot'">
  23. <block v-for="(item,index) in bannerDetail.length" :key="index">
  24. <view :class="{active: index == cur}"
  25. :style="{backgroundColor:index == cur?indicatorColor:noIndicatorColor}" class="dot"></view>
  26. </block>
  27. </view>
  28. <view class="dots-bk dots-bk1" v-if="dotsType=='digit'">
  29. <view class="tag-wrap">
  30. <text>{{cur+1+'/'+bannerDetail.length}}</text>
  31. </view>
  32. </view>
  33. </view>
  34. <!-- 收藏图标 -->
  35. <!-- <slot name="collection"></slot> -->
  36. <!--重置小圆点的样式 end -->
  37. <!-- 没有轮播时的默认图 -->
  38. <!-- <image
  39. wx:else="{{bannerDetail.length}}"
  40. class="banner-image"
  41. src="{{filters.imageFmt('good-default@2x')}}"
  42. /> -->
  43. </view>
  44. </template>
  45. <script lang="ts">
  46. import {
  47. Component,
  48. Prop,
  49. Emit,
  50. Vue
  51. } from "vue-property-decorator";
  52. @Component({})
  53. export default class swiperBanner extends Vue {
  54. @Prop({
  55. default: true
  56. }) private indicatorDots! : boolean; // 是否自定义指示点
  57. @Prop({
  58. default: 'dot'
  59. }) dotsType ?: string; // 自定义指示点样式 可选 dot / digit
  60. @Prop({
  61. default: true
  62. }) private autoPlay ?: boolean; // 自动切换
  63. @Prop() bannerDetail! : Array<any>; // 轮播数据
  64. @Prop({
  65. default: 154
  66. }) private bannerH! : number; // 轮播图高度
  67. @Prop({
  68. default: '#fff'
  69. }) private indicatorColor ?: string; // 自定义指示点颜色
  70. @Prop({
  71. default: 'rgba(255,255,255,1)'
  72. }) private noIndicatorColor ?: string; // 未选中指示点颜色
  73. @Prop({
  74. default: 0
  75. }) private radius ?: number; // 自定义圆角 默认没有
  76. @Prop({
  77. default: false
  78. }) private preview ?: boolean; // 开启预览图片 与点击跳转只可存在一个
  79. @Prop() private bannerType ?: string; //轮播样式类型
  80. @Prop({
  81. default: "0rpx"
  82. }) private previousNext ?: string; //前后轮播 缩进尺寸
  83. @Prop({
  84. default: ""
  85. }) private imgKey! : string // // 图片的字段
  86. // options:{
  87. // // 开启具名插槽
  88. // multipleSlots: true ,
  89. cur : number = 0 // 当前滑块的index
  90. swiperChange(e : any) {
  91. this.cur = e.detail.current //获取当前轮播图片的下标, 可以给当前指示点加样式
  92. this.changeIndex(e.detail.current + 1);
  93. }
  94. //点击轮播
  95. chooseSwiper(item : any) {
  96. // console.log(item)
  97. if (this.preview) {
  98. let urls = this.bannerDetail.map(res => res[this.imgKey] || res)
  99. uni.previewImage({
  100. current: item[this.imgKey] || item,
  101. loop: true,
  102. urls,
  103. })
  104. } else {
  105. this.changeSwiper(item)
  106. }
  107. }
  108. @Emit('changeSwiper')
  109. changeSwiper(val : any) {
  110. return val
  111. }
  112. @Emit('changeIndex')
  113. changeIndex(val : any) {
  114. return val
  115. }
  116. };
  117. </script>
  118. <style lang="scss" scoped>
  119. .detail-banner {
  120. width: 100%;
  121. position: relative;
  122. // background: #d8d8d8;
  123. overflow: hidden;
  124. .swiper-box {
  125. height: inherit;
  126. }
  127. .banner-image {
  128. width: 100%;
  129. height: 100%;
  130. }
  131. }
  132. .swiper-item {
  133. display: flex;
  134. justify-content: center;
  135. align-items: center;
  136. }
  137. .swiper-bigger {
  138. height: 100%
  139. }
  140. .swiper-smaller {
  141. // height:80%
  142. height: 100%
  143. }
  144. @keyframes Bigger {
  145. from {
  146. height: 80%
  147. }
  148. to {
  149. height: 100%
  150. }
  151. }
  152. @keyframes Smaller {
  153. from {
  154. height: 100%
  155. }
  156. to {
  157. height: 80%
  158. }
  159. }
  160. // 中间的轮播图
  161. .image-bigger {
  162. margin: 0 vw(10);
  163. height: 100%;
  164. width: 100%;
  165. overflow: hidden;
  166. // animation: Bigger 0.5s;
  167. // -webkit-animation: heightChange 0.7s; /* Safari 与 Chrome */
  168. }
  169. // 两边的缩小的图片
  170. .image-smaller {
  171. height: 100%;
  172. // animation: Smaller 0.5s;
  173. }
  174. .dots {
  175. position: absolute;
  176. bottom: vw(12);
  177. height: vw(10);
  178. width: 100%;
  179. @include flex-x(center)
  180. }
  181. .dots-bk {
  182. background: rgba(0, 0, 0, 0.1);
  183. height: vw(10);
  184. padding: 0 vw(3);
  185. border-radius: vw(10);
  186. @include flex-x() &.dots-bk1 {
  187. background: none
  188. }
  189. // 指示点的第二种样式
  190. .tag-wrap {
  191. position: absolute;
  192. right: vw(15);
  193. background: #333;
  194. color: #fff;
  195. height: vw(20);
  196. line-height: vw(20);
  197. padding: vw(1) vw(10);
  198. border-radius: vw(10);
  199. font-size: vw(12);
  200. }
  201. }
  202. /* 未选中时的小圆点样式 */
  203. .dot {
  204. margin-right: vw(8);
  205. border-radius: vw(6);
  206. height: vw(6);
  207. width: vw(6);
  208. margin: 0 vw(3)
  209. }
  210. /* 选中以后的小圆点样式 */
  211. .active {
  212. width: vw(12);
  213. }
  214. </style>