当前位置:   article > 正文

Vue3使用触摸滑动插件(Swiper)_vue3 swiper

vue3 swiper

Vue2使用触摸滑动插件(Swiper)

参考文档:

本文使用版本:Swiper@11.0.5

安装插件:pnpm i swiper

本文基于Swiper插件进行封装,主要实现两种形式的轮播图展示:

  • 首页轮播图切换展示(type: banner)

  • 走马灯轮播图滚动展示(type: carousel)

  • 信息展播模式(type: broadcast)

可自定义设置以下属性:

  • 轮播图片数组(images),类型:Array<{title: string, link?: string, src: string}>,默认 []

  • 图片宽度(width),类型:number | string,默认 '100%'

  • 图片高度(height),类型:number | string,默认 '100vh'

  • banner轮播图模式 | carousel走马灯模式(type),类型:'banner'|'carouse'|'broadcast',默认 'banner'

  • 是否显示导航(navigation),类型:boolean,默认 true

  • 自动切换的时间间隔(type: banner时生效)(delay),单位ms,类型:number,默认 3000

  • 是否可以鼠标拖动(swipe),类型:boolean,默认 true

  • 预加载时的loading颜色(preloaderColor),类型:'theme'|'white'|'black',默认 'theme',可选 theme(主题色) | white | black

效果如下图:在线预览

首页轮播图 type: banner

走马灯 type: carousel 

信息展播 type: broadcast

①创建触摸滑动组件Swiper.vue

  1. <script setup lang="ts">
  2. import { Swiper, SwiperSlide } from 'swiper/vue'
  3. import { Pagination, Navigation, Autoplay, EffectFade, Mousewheel } from 'swiper/modules'
  4. import 'swiper/css'
  5. import 'swiper/css/navigation'
  6. import 'swiper/css/pagination'
  7. import 'swiper/css/effect-fade'
  8. import { ref, computed } from 'vue'
  9. interface Image {
  10. title: string // 图片名称
  11. link?: string // 图片跳转链接
  12. src: string // 图片地址
  13. }
  14. interface Props {
  15. images: Image[] // 轮播图片数组
  16. width?: number|string // 图片宽度
  17. height?: number|string // 图片高度
  18. type?: 'banner'|'carousel'|'broadcast' // banner轮播图模式 | carousel走马灯模式
  19. navigation?: boolean // 是否显示导航
  20. delay?: number // 自动切换的时间间隔(type: banner时生效),单位ms
  21. swipe?: boolean // 是否可以鼠标拖动
  22. preloaderColor?: 'theme'|'white'|'black' // 预加载时的loading颜色
  23. }
  24. const props = withDefaults(defineProps<Props>(), {
  25. images: () => [],
  26. width: '100%',
  27. height: '100vh',
  28. type: 'banner', // 可选 banner | carousel
  29. navigation: true,
  30. delay: 3000,
  31. swipe: true,
  32. preloaderColor: 'theme' // 可选 theme white black
  33. })
  34. const imgWidth = computed(() => {
  35. if (typeof props.width === 'number') {
  36. return props.width + 'px'
  37. } else {
  38. return props.width
  39. }
  40. })
  41. const imgHeight = computed(() => {
  42. if (typeof props.height === 'number') {
  43. return props.height + 'px'
  44. } else {
  45. return props.height
  46. }
  47. })
  48. const modulesBanner = ref([Navigation, Pagination, Autoplay, EffectFade])
  49. const autoplayBanner = ref({
  50. delay: props.delay,
  51. disableOnInteraction: false, // 用户操作swiper之后,是否禁止autoplay。默认为true:停止。
  52. pauseOnMouseEnter: true // 鼠标置于swiper时暂停自动切换,鼠标离开时恢复自动切换,默认false
  53. })
  54. const modulesCarousel = ref([Autoplay])
  55. const autoplayCarousel = ref<object|boolean>({
  56. delay: 0,
  57. disableOnInteraction: false
  58. })
  59. const modulesBroadcast = ref([Navigation, Pagination, Mousewheel])
  60. const emits = defineEmits(['swiper', 'change'])
  61. function onSwiper (swiper: any) {
  62. // console.log(swiper)
  63. emits('swiper', swiper)
  64. if (props.type === 'carousel') {
  65. swiper.el.onmouseenter = () => { // 移入暂停
  66. swiper.autoplay.stop()
  67. }
  68. swiper.el.onmouseleave = () => { // 移出启动
  69. swiper.autoplay.start()
  70. }
  71. }
  72. }
  73. </script>
  74. <template>
  75. <swiper
  76. v-if="type==='banner'"
  77. :class="{'swiper-no-swiping': !swipe}"
  78. :modules="modulesBanner"
  79. :navigation="navigation"
  80. :slides-per-view="1"
  81. :autoplay="autoplayBanner"
  82. lazy
  83. loop
  84. @swiper="onSwiper"
  85. @slideChange="$emit('change')"
  86. v-bind="$attrs">
  87. <swiper-slide v-for="(image, index) in images" :key="index">
  88. <a :href="image.link ? image.link:'javascript:;'" :target="image.link ? '_blank':'_self'" class="m-link">
  89. <img
  90. :src="image.src"
  91. class="u-img"
  92. :style="`width: ${imgWidth}; height: ${imgHeight};`"
  93. :alt="image.title"
  94. loading="lazy" />
  95. </a>
  96. <div :class="`swiper-lazy-preloader swiper-lazy-preloader-${preloaderColor}`"></div>
  97. </swiper-slide>
  98. </swiper>
  99. <swiper
  100. v-if="type==='carousel'"
  101. class="swiper-no-swiping"
  102. :modules="modulesCarousel"
  103. :autoplay="autoplayCarousel"
  104. lazy
  105. loop
  106. @swiper="onSwiper"
  107. @slideChange="$emit('change')"
  108. v-bind="$attrs">
  109. <swiper-slide v-for="(image, index) in images" :key="index">
  110. <a :href="image.link ? image.link:'javascript:;'" :target="image.link ? '_blank':'_self'" class="m-link">
  111. <img
  112. :src="image.src"
  113. class="u-img"
  114. :style="`width: ${imgWidth}; height: ${imgHeight};`"
  115. :alt="image.title"
  116. loading="lazy" />
  117. </a>
  118. <div :class="`swiper-lazy-preloader swiper-lazy-preloader-${preloaderColor}`"></div>
  119. </swiper-slide>
  120. </swiper>
  121. <swiper
  122. v-if="type==='broadcast'"
  123. :modules="modulesBroadcast"
  124. :navigation="navigation"
  125. lazy
  126. @swiper="onSwiper"
  127. @slideChange="$emit('change')"
  128. v-bind="$attrs">
  129. <swiper-slide v-for="(image, index) in images" :key="index">
  130. <a :href="image.link ? image.link:'javascript:;'" :target="image.link ? '_blank':'_self'" class="m-link">
  131. <img
  132. :src="image.src"
  133. class="u-img"
  134. :style="`width: ${imgWidth}; height: ${imgHeight};`"
  135. :alt="image.title"
  136. loading="lazy" />
  137. </a>
  138. <div :class="`swiper-lazy-preloader swiper-lazy-preloader-${preloaderColor}`"></div>
  139. </swiper-slide>
  140. </swiper>
  141. </template>
  142. <style lang="less" scoped>
  143. .m-link {
  144. display: block;
  145. height: 100%;
  146. }
  147. .u-img {
  148. object-fit: cover;
  149. cursor: pointer;
  150. }
  151. .swiper {
  152. --swiper-theme-color: @themeColor;
  153. }
  154. :deep(.swiper-wrapper) { // 自动切换过渡效果设置
  155. transition-timing-function: linear; // 线性过渡模拟走马灯效果
  156. -webkit-transition-timing-function: linear;
  157. }
  158. :deep(.swiper-pagination-bullet) {
  159. width: 12px;
  160. height: 12px;
  161. }
  162. .swiper-lazy-preloader-theme {
  163. --swiper-preloader-color: @themeColor;
  164. }
  165. </style>

②在要使用的页面引入:

  1. <script setup lang="ts">
  2. import Swiper from './Swiper.vue'
  3. import pkg from '/package.json'
  4. import { ref, shallowReactive, onBeforeMount } from 'vue'
  5. const images = ref<any[]>([])
  6. function loadImages () {
  7. for (let i = 1; i <= 10; i++) {
  8. images.value.push({
  9. title: `image-${i}`,
  10. link: `https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/${i}.jpg`,
  11. src: `https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/${i}.jpg`
  12. })
  13. }
  14. }
  15. onBeforeMount(() => { // 组件已完成响应式状态设置,但未创建DOM节点
  16. loadImages()
  17. })
  18. function onChange () {
  19. console.log('slider change')
  20. }
  21. const navigation = shallowReactive<{[key: string]: any}>({})
  22. function onSwiper (swiper: any) {
  23. navigation.prevEl = swiper.navigation.prevEl
  24. navigation.prevEl.style.display = 'none'
  25. navigation.nextEl = swiper.navigation.nextEl
  26. navigation.nextEl.style.display = 'none'
  27. }
  28. function onPrev () {
  29. navigation.prevEl.click()
  30. }
  31. function onNext () {
  32. navigation.nextEl.click()
  33. }
  34. </script>
  35. <template>
  36. <div>
  37. <h1>Swiper 参考文档</h1>
  38. <ul class="m-list">
  39. <li>
  40. <a class="u-file" href="https://swiperjs.com/" target="_blank">Swiper官方</a>
  41. </li>
  42. <li>
  43. <a class="u-file" href="https://swiperjs.com/swiper-api" target="_blank">Swiper API</a>
  44. </li>
  45. <li>
  46. <a class="u-file" href="https://swiperjs.com/vue" target="_blank">Swiper Vue</a>
  47. </li>
  48. <li>
  49. <a class="u-file" href="https://swiperjs.com/demos" target="_blank">Swiper Demos</a>
  50. </li>
  51. </ul>
  52. <Space align="top" class="mt30" :size="6">
  53. <h1>Swiper</h1>
  54. <Tag color="volcano">{{ pkg.dependencies.swiper }}</Tag>
  55. </Space>
  56. <h2 class="mt30 mb10">基本使用</h2>
  57. <Swiper
  58. :images="images"
  59. :height="600"
  60. :pagination="{
  61. dynamicBullets: true,
  62. clickable: true
  63. }"
  64. @change="onChange" />
  65. <h2 class="mt30 mb10">走马灯</h2>
  66. <Swiper
  67. :images="images"
  68. type="carousel"
  69. :height="240"
  70. :slides-per-view="3"
  71. :space-between="20"
  72. :speed="2500" />
  73. <h2 class="mt30 mb10">信息展播</h2>
  74. <Space>
  75. <Button @click="onPrev">Prev</Button>
  76. <Button @click="onNext">Next</Button>
  77. </Space>
  78. <br/>
  79. <br/>
  80. <Swiper
  81. :images="images"
  82. type="broadcast"
  83. :pagination="{
  84. dynamicBullets: true,
  85. clickable: true
  86. }"
  87. :height="320"
  88. :slides-per-view="3"
  89. :space-between="30"
  90. loop
  91. mousewheel
  92. @swiper="onSwiper" />
  93. </div>
  94. </template>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/232016
推荐阅读
相关标签
  

闽ICP备14008679号