swiper.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <view class="banner" :style="{height: height + 'rpx'}">
  3. <view v-for="(item, index) in list" :key="index" class="pic"
  4. :animation="num === index ?showpic:hidepic"
  5. :style="{zIndex: zIndex === index ?1:0}"
  6. @touchstart="touchstart" @touchend="touchend">
  7. <!--#ifdef MP -->
  8. <app-jump-button
  9. :open_type="item.open_type"
  10. :url="item.url ? item.url : item.page_url"
  11. :params="item.params">
  12. <image :style="{height: height + 'rpx', width: '100%'}" :mode="imgMode" :src="item[name]" />
  13. </app-jump-button>
  14. <!--#endif-->
  15. <!--#ifdef H5 -->
  16. <app-jump-button
  17. v-if="item.open_type !== 'app'"
  18. :open_type="item.open_type"
  19. :url="item.url ? item.url : item.page_url"
  20. :params="item.params">
  21. <image :style="{height: height + 'rpx', width: '100%'}" :mode="imgMode" :src="item[name]" />
  22. </app-jump-button>
  23. <view :id="item.id" v-if="item.open_type === 'app'" style="height: 100%;">
  24. </view>
  25. <!-- <view :id="'swiper-' + index" style="height: 100%;">-->
  26. <!-- </view>-->
  27. <!-- <wx-open-launch-weapp v-if="item.open_type === 'app' && isWechat" id="launch-btn" :username="getUrlParam(item.page_url, 'username')" :path="getUrlParam(item.page_url, 'path')">-->
  28. <!-- <script type="text/wxtag-template">-->
  29. <!-- <image :style="{height: height + 'rpx', width: '100%'}" :mode="imgMode" :src="item[name]" />-->
  30. <!-- </script>-->
  31. <!-- </wx-open-launch-weapp>-->
  32. <!--#endif-->
  33. </view>
  34. <view class="u-swiper-indicator"
  35. :style="{
  36. bottom: '12rpx',
  37. justifyContent: 'center'
  38. }"
  39. >
  40. <block v-if="mode === 'rect'">
  41. <view class="u-indicator-item-rect" :class="{ 'u-indicator-item-rect-active': index === num }" v-for="(item, index) in list"
  42. :key="index"></view>
  43. </block>
  44. <block v-if="mode === 'round'">
  45. <view class="u-indicator-item-round" :class="{ 'u-indicator-item-round-active': index === num }" v-for="(item, index) in list"
  46. :key="index"></view>
  47. </block>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. export default {
  53. name:'u-swiper',
  54. props: {
  55. list: {
  56. type: Array,
  57. default () {
  58. return [];
  59. }
  60. },
  61. // 图片的裁剪模式
  62. imgMode: {
  63. type: String,
  64. default: 'aspectFill'
  65. },
  66. // 从list数组中读取的图片的属性名
  67. name: {
  68. type: String,
  69. default: 'image'
  70. },
  71. // list的高度,单位rpx
  72. height: {
  73. type: [Number, String],
  74. default: 250
  75. },
  76. // 自动轮播时间间隔,单位ms
  77. duration: {
  78. type: [Number, String],
  79. default: 500
  80. },
  81. // 隔多久自动切换
  82. interval: {
  83. type: [String, Number],
  84. default: 3000
  85. },
  86. // 指示器的模式,rect|dot|number|round
  87. mode: {
  88. type: String,
  89. default: 'round'
  90. },
  91. // 指示器的位置,topLeft|topCenter|topRight|bottomLeft|bottomCenter|bottomRight
  92. indicatorPos: {
  93. type: String,
  94. default: 'bottomCenter'
  95. },
  96. // 是否自动播放
  97. autoplay: {
  98. type: Boolean,
  99. default: true
  100. },
  101. },
  102. data() {
  103. return {
  104. num: 0,
  105. zIndex: 0,
  106. showpic:null,
  107. hidepic:null,
  108. setTime: 0,
  109. touchDot: 0
  110. }
  111. },
  112. // #ifdef H5
  113. created() {
  114. this.$jwx.config();
  115. },
  116. // #endif
  117. methods: {
  118. touchstart(e) {
  119. this.touchDot = e.touches[0].pageX;
  120. },
  121. touchend(e) {
  122. let touchMove = e.changedTouches[0].pageX;
  123. if (touchMove - this.touchDot <= -40) {
  124. this.num = this.num - 1;
  125. if(this.num < 0){
  126. this.num=this.list.length-1;
  127. }
  128. setTimeout(() => {
  129. this.zIndex = this.num;
  130. }, 1000);
  131. }
  132. if (touchMove - this.touchDot >= 40) {
  133. this.num = this.num + 1;
  134. if(this.num>=this.list.length){
  135. this.num=0;
  136. }
  137. setTimeout(() => {
  138. this.zIndex = this.num;
  139. }, 1000);
  140. }
  141. },
  142. getUrlParam(url,name) {
  143. let search = url.split('?')[1];
  144. if (search) {
  145. let r = search.substr(0).match(new RegExp('(^|&)' + name + '=([^&]*)(&|$)'))
  146. if (r !== null) return unescape(r[2])
  147. return null
  148. } else {
  149. return null
  150. }
  151. }
  152. },
  153. destroyed() {
  154. clearInterval(this.setTime);
  155. },
  156. watch: {
  157. list: {
  158. handler(newVal) {
  159. if (newVal.length === 0) return;
  160. let animation= uni.createAnimation({}) //创建一个动画实例
  161. //淡入
  162. animation.opacity(1).step({
  163. duration:this.duration
  164. }) //描述动画
  165. this.showpic = animation.export();
  166. //淡出
  167. animation.opacity(0).step({duration:this.duration});
  168. // #ifdef H5
  169. // #endif
  170. this.hidepic = animation.export();
  171. if (this.autoplay) {
  172. this.setTime = setInterval(() => {
  173. this.num = this.num+1;
  174. if(this.num>=this.list.length){
  175. this.num=0;
  176. }
  177. setTimeout(() => {
  178. this.zIndex = this.num;
  179. }, this.interval + 1000)
  180. }, this.interval);
  181. }
  182. // #ifdef H5
  183. for (let i = 0; i < newVal.length; i++) {
  184. if (newVal[i].open_type === 'app') {
  185. newVal[i].id = this.$utils.guid('swiper');
  186. let height = uni.upx2px(this.height)+ 'px';
  187. let username = this.getUrlParam(newVal[i].page_url, 'username');
  188. let path = this.getUrlParam(newVal[i].page_url, 'path');
  189. let text = `<img src="${newVal[i].pic_url}" width="100%" height="${height}" />`;
  190. this.$utils.createWxOpenLaunchWeapp(newVal[i].id, username, path, text);
  191. }
  192. }
  193. // #endif
  194. },
  195. immediate: true
  196. }
  197. },
  198. // #ifdef H5
  199. computed: {
  200. isWechat: function() {
  201. return this.$jwx.isWechat();
  202. }
  203. }
  204. // #endif
  205. }
  206. </script>
  207. <style lang="scss">
  208. .banner {
  209. width: 750rpx;
  210. position: relative;
  211. }
  212. .pic {
  213. width:750rpx;
  214. position:absolute;
  215. top:0;
  216. left:0;
  217. }
  218. .u-swiper-indicator {
  219. padding: 0 24rpx;
  220. position: absolute;
  221. display: flex;
  222. width: 100%;
  223. z-index: 1;
  224. }
  225. .u-indicator-item-round-active {
  226. width: 34rpx !important;
  227. background-color: rgba(255, 255, 255, 0.8) !important;
  228. }
  229. .u-indicator-item-round {
  230. width: 14rpx;
  231. height: 14rpx;
  232. margin: 0 6rpx;
  233. border-radius: 20rpx;
  234. transition: all 0.5s;
  235. background-color: rgba(0, 0, 0, 0.3);
  236. }
  237. .u-indicator-item-rect {
  238. width: 26rpx;
  239. height: 8rpx;
  240. margin: 0 6rpx;
  241. transition: all 0.5s;
  242. background-color: rgba(0, 0, 0, 0.3);
  243. }
  244. .u-indicator-item-rect-active {
  245. background-color: rgba(255, 255, 255, 0.8);
  246. }
  247. </style>