e-swiper.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <!-- 轮播图 -->
  3. <view class="Swiper-mfw-index-box">
  4. <view class="Swiper-mfw-index Swiper-box" :class="[dotPosition]">
  5. <swiper class="Swiper-mfw" :style="{ height: height }" :circular="true" :indicator-dots="false"
  6. :autoplay="autoplay" :interval="3000" :duration="1000" :current="currentIndex"
  7. :disable-touch="disable_touch" @change="change">
  8. <!-- 只需要前5条数据 -->
  9. <block v-for="(item, index) in list" :key="index">
  10. <swiper-item class="swiper-mfw-item" v-if="index <= 4">
  11. <!-- /*
  12. 1. 这里不需要用api控制暂停视频
  13. 2. 因为video标签上加了v-if="current==index"
  14. 3. 当current == index时才会创建视频组件
  15. 4. 否current != index则就销毁视频
  16. */ -->
  17. <!-- 如果有视频,则显示视频-->
  18. <template v-if="item.mp4 && current == index">
  19. <video class="ImageVideo" :id="'ImageVideo' + index" :ref="'ImageVideo' + index"
  20. :src="item.mp4" :loop="true" :muted="false" :autoplay="current == index ? true : false"
  21. :controls="false" :show-fullscreen-btn="false" :show-play-btn="false"
  22. :enable-progress-gesture="false" :play-strategy="0"
  23. :poster="item.image || item.src"></video>
  24. </template>
  25. <!-- 否则显示图片 -->
  26. <image v-else :src="item.image || item.src" class="Image" mode="aspectFill"
  27. @click.stop="$emit('on-click', item)"></image>
  28. </swiper-item>
  29. </block>
  30. </swiper>
  31. <!-- 指示器 [Top] -->
  32. <view v-if="useTop" class="Swiper-indicator-box indicator-Top-box">
  33. <!-- Top顶部 [今日首推-盒子] -->
  34. <view class="Top-date-hot">
  35. <view class="left-date-ri">
  36. <text class="date-ri-text text">{{ date.month }}</text>
  37. </view>
  38. <view class="conter-date-nianyue">
  39. <view class="left-width-bgcolor"></view>
  40. <view class="right-date-nianyue">
  41. <text class="Top-yue-usa text">{{ date.monthEn }}</text>
  42. <text class="Bottom-nian text">{{ date.year }}</text>
  43. </view>
  44. </view>
  45. <view class="right-hot-ttf">
  46. <text class="text hot-text">{{ title }}</text>
  47. </view>
  48. </view>
  49. </view>
  50. <!-- 指示器 标题区域 -->
  51. <view v-if="useTitle" class="Swiper-indicator-Top" :class="{ 'no-dot': !useDot }">
  52. <block v-for="(item, index) in list" :key="index">
  53. <view v-if="currentIndex == index" class="Top-item" :class="current == index ? 'current' : 'no'">
  54. <!-- 如果存在视频,则显示“视频预览”提示 -->
  55. <view v-if="item.mp4" class="Top-ImageVideo">
  56. <!-- icon图标 -->
  57. <view class="Icons">
  58. <!-- 播放按钮图标 -->
  59. <text class="iconfont icon-caret-right"></text>
  60. </view>
  61. <text class="text ImageVideo-text app-ttf">视频预览</text>
  62. </view>
  63. <!-- 标题 -->
  64. <view class="Top-Title">
  65. <text class="text title-text">{{ item.title }}</text>
  66. </view>
  67. <!-- 用户信息 -->
  68. <view class="Bottom-UserInfo">
  69. <!-- 头像 -->
  70. <view class="UserImage-box">
  71. <image :src="item.avatar" class="Image" mode="aspectFill"></image>
  72. </view>
  73. <!-- 用户名 -->
  74. <view class="textbox UserName-box">
  75. <text class="text UserInfo">{{ item.nickname }}</text>
  76. </view>
  77. <view v-if="item.createTime" class="jiange-box"><text class="text jiange-text"></text>
  78. </view>
  79. <view v-if="item.createTime" class="textbox UserGPS-box">
  80. <text class="text UserInfo">发布于 {{ item.createTime }}</text>
  81. </view>
  82. <view v-if="item.address" class="jiange-box"><text class="text jiange-text">·</text></view>
  83. <view v-if="item.address" class="textbox UserGPS-box">
  84. <text class="text UserInfo">{{ item.address }}</text>
  85. </view>
  86. </view>
  87. </view>
  88. </block>
  89. </view>
  90. <!-- 指示器 [左边图片列表+右边按钮] -->
  91. <view v-if="useDot" class="Swiper-indicator-Bottom">
  92. <!-- 左边 -->
  93. <view class="Bottom-left-Imagelist">
  94. <block v-for="(item, index) in list" :key="index">
  95. <view class="Bottom-item" v-if="Number(index) <= 4"
  96. :class="currentIndex == index ? 'current' : 'no'" @click="SwiperIndTap(index)">
  97. <image :src="item.image || item.src" class="Image" mode="aspectFill"></image>
  98. </view>
  99. </block>
  100. </view>
  101. <!-- 右边 -->
  102. <view v-if="false" class="Bottom-right-lili-btn">
  103. <view class="Bottom-item is-more">
  104. <view class="more" @click.stop="$emit('on-more')">
  105. MORE
  106. <text class="iconfont icon-caret-right"></text>
  107. </view>
  108. <text class="left text indicator-text">更多推荐</text>
  109. </view>
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. </template>
  115. <script>
  116. export default {
  117. name: 'e-swiper',
  118. props: {
  119. title: {
  120. type: String,
  121. default: ''
  122. },
  123. height: {
  124. type: String,
  125. default: '450rpx'
  126. },
  127. dotPosition: {
  128. type: String,
  129. default: 'bottom'
  130. },
  131. useTop: {
  132. type: Boolean,
  133. default: true
  134. },
  135. useDot: {
  136. type: Boolean,
  137. default: true
  138. },
  139. useTitle: {
  140. type: Boolean,
  141. default: true
  142. },
  143. useUser: {
  144. type: Boolean,
  145. default: true
  146. },
  147. // 轮播图 数据列表
  148. list: {
  149. type: Array,
  150. default: () => []
  151. },
  152. // 当前选中的项(指示器坐标位置)
  153. current: {
  154. type: Number,
  155. default: 0
  156. },
  157. // 是否自动轮播
  158. autoplay: {
  159. type: Boolean,
  160. default: false
  161. }
  162. },
  163. data() {
  164. return {
  165. // 是否禁止用户 touch 操作
  166. currentIndex: 0,
  167. disable_touch: false, //touch 用户划动引起swiper变化。
  168. date: {
  169. year: '-',
  170. monthEn: '-',
  171. month: '-'
  172. }
  173. };
  174. },
  175. created() {
  176. this.currentIndex = this.current;
  177. const date = new Date();
  178. //将月份名称存储在数组中
  179. const monthArray = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov',
  180. 'Dec');
  181. this.date.year = date.getFullYear();
  182. let month = date.getMonth() + 1;
  183. this.date.month = month < 10 ? '0' + month : month;
  184. this.date.monthEn = monthArray[date.getMonth()].toUpperCase();
  185. },
  186. methods: {
  187. // current 改变时会触发 change 事件,event.detail = {current: current, source: source}
  188. change(e) {
  189. let {
  190. current,
  191. source
  192. } = e.detail;
  193. //只有页面自动切换,手动切换时才轮播,其他不允许
  194. if (source === 'autoplay' || source === 'touch') {
  195. let event = {
  196. current: current
  197. };
  198. this.currentIndex = current;
  199. this.$emit('change', event);
  200. }
  201. },
  202. // 手动点击了指示器[小图模式]
  203. SwiperIndTap(e) {
  204. let index = e;
  205. let event = {
  206. current: index
  207. };
  208. this.currentIndex = index;
  209. this.$emit('change', event);
  210. }
  211. }
  212. };
  213. </script>
  214. <style lang="scss" scoped>
  215. @import './e-swiper.scss';
  216. </style>