gui-swiper.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <template>
  2. <view class="gui-swiper-card-wrap">
  3. <swiper
  4. :style="{
  5. width:width+'rpx',
  6. height:heightIn+'rpx'
  7. }"
  8. class="gui-swiper-card"
  9. :indicator-dots="false"
  10. :interval="interval"
  11. :circular="true"
  12. :autoplay="autoplay"
  13. :current="currentIndex"
  14. :previous-margin="spacing+'rpx'"
  15. :next-margin="spacing+'rpx'"
  16. @change="swiperchange">
  17. <swiper-item
  18. v-for="(item, index) in swiperItems"
  19. :key="index"
  20. class="gui-swiper-card-item gui-border-box">
  21. <navigator
  22. class="gui-swiper-card-nav gui-transition-all"
  23. :url="item.url"
  24. :open-type="item.opentype"
  25. hover-class="none"
  26. v-if="item.opentype != 'click'"
  27. :style="{
  28. paddingLeft:current != index ? padding +'rpx':'0rpx',
  29. paddingRight:current != index ? padding +'rpx':'0rpx',
  30. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  31. paddingBottom:current != index ? paddingY +'rpx':'0rpx'
  32. }">
  33. <image
  34. :style="{
  35. borderRadius : borderRadius,
  36. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  37. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  38. opacity:current != index ? opacity : 1
  39. }"
  40. :src="item.img"
  41. :mode="imgMode"
  42. class="gui-swiper-card-image gui-transition-all" />
  43. </navigator>
  44. <view
  45. class="gui-swiper-card-nav gui-transition-all"
  46. hover-class="none"
  47. v-if="item.opentype == 'click'"
  48. @tap.stop="taped"
  49. :data-index="index"
  50. :style="{
  51. paddingLeft:current != index ? padding +'rpx':'0rpx',
  52. paddingRight:current != index ? padding +'rpx':'0rpx',
  53. paddingTop:current != index ? paddingY +'rpx':'0rpx',
  54. paddingBottom:current != index ? paddingY +'rpx':'0rpx'
  55. }">
  56. <image
  57. :style="{
  58. borderRadius : borderRadius,
  59. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  60. height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
  61. opacity:current != index ? opacity : 1
  62. }"
  63. :src="item.img"
  64. :mode="imgMode"
  65. class="gui-swiper-card-image gui-transition-all" />
  66. </view>
  67. <view
  68. v-if="indicatorType == 'number'"
  69. class="gui-indicator-dot-numbers gui-flex gui-row gui-nowrap"
  70. :class="indicatorBarBgClass"
  71. :style="{
  72. height:indicatorBarHeight+'rpx',
  73. 'border-bottom-left-radius':borderRadius,
  74. 'border-bottom-right-radius':borderRadius,
  75. width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
  76. left:current != index ? padding+'rpx':'0rpx',
  77. bottom:current != index ? paddingY+'rpx':'0rpx'
  78. }">
  79. <text
  80. class="gui-indicator-dot-text"
  81. :style="{
  82. paddingLeft:'20rpx',
  83. 'fontStyle':'italic',
  84. color:titleColor
  85. }">{{index+1}}</text>
  86. <text
  87. class="gui-indicator-dot-text"
  88. :style="{
  89. 'fontSize':'36rpx',
  90. color:titleColor
  91. }">/</text>
  92. <text
  93. class="gui-indicator-dot-text"
  94. :style="{
  95. fontSize:'28rpx',
  96. paddingRight:'20rpx',
  97. fontStyle:'italic',
  98. color:titleColor
  99. }">{{swiperItems.length}}</text>
  100. <text
  101. class="gui-swiper-text gui-block-text gui-flex1 gui-ellipsis"
  102. :style="{
  103. color:titleColor,
  104. fontSize:titleSize,
  105. height:indicatorBarHeight+'rpx',
  106. lineHeight:indicatorBarHeight+'rpx'
  107. }">{{item.title}}</text>
  108. </view>
  109. </swiper-item>
  110. </swiper>
  111. <!-- 进度圆点 -->
  112. <view
  113. class="gui-indicator-dots gui-flex gui-row gui-nowrap gui-justify-content-center gui-align-items-center gui-border-box"
  114. v-if="indicatorType == 'dot'"
  115. :style="{
  116. width:width+'rpx',
  117. height:indicatorBarHeight+'rpx',
  118. position:indicatorPosition,
  119. paddingLeft:spacing+'rpx',
  120. paddingRight:spacing+'rpx',
  121. 'justify-content':indicatorDirection
  122. }">
  123. <view
  124. class="gui-indicator-dots-wrap gui-flex gui-row gui-nowrap gui-justify-content-center">
  125. <view
  126. v-for="(item, index) in swiperItems"
  127. :key="index"
  128. :class="[
  129. 'gui-indicator-dot',
  130. current == index ? 'dot-show' : '',
  131. current == index ? indicatorActiveClass : indicatorClass
  132. ]"
  133. :style="{
  134. width : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
  135. height : indicatorHeight+'rpx',
  136. borderRadius : indicatorRadius+'rpx',
  137. }"></view>
  138. </view>
  139. </view>
  140. </view>
  141. </template>
  142. <script>
  143. export default{
  144. name : "gui-swiper",
  145. props : {
  146. width :{ type : Number, default : 750 },
  147. height:{ type : Number, default : 300 },
  148. swiperItems : {
  149. type : Array,
  150. default : function(){
  151. return new Array();
  152. }
  153. },
  154. borderRadius : { type : String, default : '10rpx'},
  155. indicatorBarHeight:{type : Number, default : 68},
  156. indicatorBarBgClass:{
  157. type : Array,
  158. default : function(){
  159. return ['gui-bg-black-opacity5'];
  160. }
  161. },
  162. indicatorWidth : { type:Number, default:18 },
  163. indicatorActiveWidth :{ type:Number, default:18 },
  164. indicatorHeight : { type:Number, default:18 },
  165. indicatorRadius:{ type:Number, default:18 },
  166. indicatorClass : {
  167. type : Array,
  168. default : function(){
  169. return ['gui-bg-gray','gui-dark-bg-level-5'];
  170. }
  171. },
  172. indicatorActiveClass : {
  173. type : Array,
  174. default : function(){
  175. return ['gui-bg-primary'];
  176. }
  177. },
  178. indicatorType:{ type : String, default : "dot" },
  179. indicatorPosition:{ type : String, default : "absolute" },
  180. indicatorDirection:{type:String, default:'center'},
  181. // #ifndef APP-NVUE
  182. spacing : { type : Number, default : 50 },
  183. // #endif
  184. // #ifdef APP-NVUE
  185. spacing : { type : Number, default : 0 },
  186. // #endif
  187. // #ifdef APP-NVUE
  188. padding : { type : Number, default : 0 },
  189. // #endif
  190. // #ifndef APP-NVUE
  191. padding : { type : Number, default : 26 },
  192. // #endif
  193. interval : { type : Number, default : 5000 },
  194. autoplay : { type : Boolean, default : true },
  195. currentIndex : { type : Number, default : 0 },
  196. opacity:{ type : Number, default:0.66},
  197. titleColor:{type:String, default:"#FFFFFF"},
  198. titleSize:{type:String, default:"28rpx"},
  199. imgMode:{type:String, default:'aspectFill'}
  200. },
  201. data() {
  202. return {
  203. current : 0,
  204. isReady : false,
  205. widthIn : 750,
  206. heightIn : 300,
  207. widthInSamll:700,
  208. heightInSmall:280,
  209. paddingY:0
  210. }
  211. },
  212. watch:{
  213. currentIndex : function (val) {
  214. this.current = val;
  215. }
  216. },
  217. created:function(){
  218. this.current = this.currentIndex;
  219. this.init();
  220. },
  221. methods:{
  222. init : function(){
  223. // 图片宽高计算
  224. this.widthIn = this.width - this.spacing*2;
  225. this.heightIn = this.height / this.width * this.widthIn;
  226. this.paddingY = this.padding * this.height / this.width;
  227. this.widthInSamll = this.widthIn - this.padding * 2;
  228. this.heightInSmall = this.heightIn - this.paddingY * 2;
  229. },
  230. swiperchange : function (e) {
  231. var current = e.detail.current;
  232. this.current = current;
  233. this.$emit('swiperchange', current);
  234. },
  235. taped : function(e){
  236. this.$emit('taped', e.currentTarget.dataset.index);
  237. }
  238. },
  239. emits : ['swiperchange', 'taped']
  240. }
  241. </script>
  242. <style scoped>
  243. .gui-swiper-card-wrap{position:relative;}
  244. .gui-swiper-card{overflow:hidden;}
  245. .gui-swiper-card-item{font-size:0; overflow:hidden; line-height:0;}
  246. .gui-swiper-card-nav{font-size:0; position:relative;}
  247. .gui-indicator-dots{width:750rpx; overflow:hidden; z-index:1; left:0; bottom:0;}
  248. .gui-indicator-dot{margin:6rpx;}
  249. .gui-indicator-dots-wrap{padding:0 20rpx;}
  250. .gui-indicator-dot-text{text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx;}
  251. .gui-indicator-dot-numbers{overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}
  252. .gui-swiper-text{width:200rpx; line-height:68rpx; padding-right:25rpx; overflow:hidden;}
  253. /* #ifndef APP-NVUE */
  254. @keyframes dot-show{from{opacity:0.1;}to{opacity:1;}}
  255. .dot-show{animation:dot-show 300ms linear forwards;}
  256. /* #endif */
  257. </style>