graceSwiper.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <template>
  2. <view class="grace-swiper-card-wrap">
  3. <swiper :style="{width:width+'rpx', height:heightIn+'rpx'}" class="grace-swiper-card"
  4. :indicator-dots="false" :interval="interval" :circular="true" :autoplay="autoplay" :current="currentIndex"
  5. :previous-margin="spacing+'rpx'" :next-margin="spacing+'rpx'" @change="swiperchange">
  6. <swiper-item v-for="(item, index) in swiperItems" :key="index" class="grace-swiper-card-item">
  7. <navigator class="grace-swiper-card-nav" :url="item.url" :open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'"
  8. :style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
  9. paddingRight:current != index ? padding +'rpx':'0rpx',
  10. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  11. paddingBottom:current != index ? paddingY +'rpx':'0rpx'}">
  12. <image :style="{
  13. borderRadius : borderRadius,
  14. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  15. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  16. opacity:current != index ? opacity : 1
  17. }" :src="item.img" class="grace-swiper-card-image" />
  18. </navigator>
  19. <view class="grace-swiper-card-nav" hover-class="none" v-if="item.opentype == 'click'" @tap.stop="taped" :data-index="index"
  20. :style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
  21. paddingRight:current != index ? padding +'rpx':'0rpx',
  22. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  23. paddingBottom:current != index ? paddingY +'rpx':'0rpx'}">
  24. <image :style="{
  25. borderRadius : borderRadius,
  26. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  27. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  28. opacity:current != index ? opacity : 1
  29. }"
  30. :src="item.img" class="grace-swiper-card-image" />
  31. </view>
  32. <view v-if="indicatorType == 'number'" class="grace-indicator-dot-numbers"
  33. :style="{
  34. height:indicatorBarHeight+'rpx', backgroundColor:indicatorBarBgColor,
  35. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  36. left:current != index ? padding+'rpx':'0rpx', bottom:current != index ? paddingY+'rpx':'0rpx'}">
  37. <text class="grace-indicator-dot-text" :style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
  38. <text class="grace-indicator-dot-text" :style="{'fontSize':'36rpx', color:titleColor}">/</text>
  39. <text class="grace-indicator-dot-text" :style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
  40. <text class="grace-swiper-text" :style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx', lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
  41. </view>
  42. </swiper-item>
  43. </swiper>
  44. <view class="grace-indicator-dots" :style="{
  45. width:width+'rpx', height:indicatorBarHeight+'rpx', paddingLeft:spacing+'rpx', paddingRight:spacing+'rpx'}">
  46. <view v-for="(item, index) in swiperItems" :key="index" :class="['grace-indicator-dot',current == index ? 'dot-show' : '']" v-if="indicatorType == 'dot'"
  47. :style="{
  48. width : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
  49. height : indicatorHeight+'rpx',
  50. borderRadius : indicatorRadius+'rpx',
  51. backgroundColor : current != index ? indicatorColor : indicatorActiveColor
  52. }"></view>
  53. </view>
  54. </view>
  55. </template>
  56. <script>
  57. export default{
  58. props:{
  59. width:{ type : Number, default : 750 },
  60. height:{ type : Number, default : 300 },
  61. swiperItems : { type : Array, default : function(){return new Array();} },
  62. borderRadius : { type : String, default : '10rpx'},
  63. indicatorBarHeight:{type : Number, default : 68},
  64. indicatorBarBgColor:{type : String, default : 'rgba(0,0,0,0)'},
  65. indicatorWidth : { type:Number, default:18 },
  66. indicatorActiveWidth :{ type:Number, default:18 },
  67. indicatorHeight : { type:Number, default:18 },
  68. indicatorRadius:{ type:Number, default:18 },
  69. indicatorColor : { type : String, default : "rgba(255, 255, 255, 0.6)" },
  70. indicatorActiveColor : { type : String, default : "#3688FF" },
  71. indicatorType:{ type : String, default : "dot" },
  72. spacing : { type : Number, default : 50 },
  73. padding : { type : Number, default : 26 },
  74. interval : { type : Number, default : 5000 },
  75. autoplay : { type : Boolean, default : true },
  76. currentIndex : { type : Number, default : 0 },
  77. opacity:{ type : Number, default:0.66},
  78. titleColor:{type:String, default:"#FFFFFF"},
  79. titleSize:{type:String, default:"28rpx"}
  80. },
  81. data() {
  82. return {
  83. current : 0,
  84. isReady : false,
  85. widthIn : 750,
  86. heightIn : 300,
  87. widthInSamll:700,
  88. heightInSmall:280,
  89. paddingY:0
  90. }
  91. },
  92. watch:{
  93. currentIndex : function (val) {
  94. this.current = val;
  95. }
  96. },
  97. created:function(){
  98. this.current = this.currentIndex;
  99. this.init();
  100. },
  101. methods:{
  102. init : function(){
  103. // 图片宽高计算
  104. this.widthIn = this.width - this.spacing*2;
  105. this.heightIn = this.height / this.width * this.widthIn;
  106. this.paddingY = this.padding * this.height / this.width;
  107. this.widthInSamll = this.widthIn - this.padding * 2;
  108. this.heightInSmall = this.heightIn - this.paddingY * 2;
  109. },
  110. swiperchange : function (e) {
  111. var current = e.detail.current;
  112. this.current = current;
  113. this.$emit('swiperchange', current);
  114. },
  115. taped : function(e){
  116. this.$emit('taped', e.currentTarget.dataset.index);
  117. }
  118. }
  119. }
  120. </script>
  121. <style scoped>
  122. .grace-swiper-card-wrap{position:relative;}
  123. .grace-swiper-card{overflow:hidden;}
  124. .grace-swiper-card-item{box-sizing:border-box; font-size:0; overflow:hidden; line-height:0;}
  125. .grace-swiper-card-nav{font-size:0; display:block; position:relative;}
  126. .grace-swiper-card-image{}
  127. .grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; position:absolute; z-index:1; left:0; bottom:0; display:flex; flex-direction:row; flex-wrap:nowrap; box-sizing:border-box; align-items:center; justify-content:center;}
  128. .grace-indicator-dot{margin:6rpx;}
  129. .grace-indicator-dot-text{display:block; text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx; flex-shrink:0;}
  130. .grace-indicator-dot-numbers{display:flex; flex-direction:row; flex-wrap:nowrap; justify-content:center; overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}
  131. .grace-swiper-text{width:750rpx; line-height:68rpx; padding-right:25rpx; box-sizing:border-box; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
  132. @keyframes dot-show{from{opacity:0.1;}to{opacity:1;}}
  133. .dot-show{animation:dot-show 300ms linear forwards;}
  134. </style>