使用vue3+ts完成swiper缩略图的效果,起初以为这个swiper是一个组件就可以完成,但现实是两个swiper做了属性互调,官网上没有描述清楚缩略图是否可以轮播,导致走了很多弯路(获取上图的实例然后操作swiper使其完成走马灯的效果)
1.安装并引入
yarn add swiper // 安装swiper依赖
2.在main.ts中引入他的css文件
import "swiper/css"
3.在你所需的页面中引入
<template>
<div style="height: 100vh; overflow: hidden">
<swiper
class="swiper mySwiper2"
:spaceBetween="10"
:thumbs="{ swiper: thumbsSwiper }"
:modules="modules"
:loop="true"
:autoplay="true"
:navigation="true"
>
<swiper-slide v-for="(item, index) of slides" :key="index">
<img class="img" :src="item" @click="toDetail" />
</swiper-slide>
</swiper>
<swiper
@swiper="setThumbsSwiper"
:spaceBetween="10"
class="swiper mySwiper"
:slidesPerView="4"
:watchSlidesProgress="true"
:modules="modules"
:autoplay="true"
:loop="true"
>
<swiper-slide v-for="(item, index) of slides" :key="index">
<img class="img" :src="item" />
</swiper-slide>
</swiper>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import "swiper/css";
import "swiper/css/free-mode";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/thumbs";
import { Thumbs, Navigation, Autoplay, Zoom, FreeMode } from "swiper/modules";
const modules = [Thumbs, Navigation, Autoplay, Zoom, FreeMode]; //必须要在这里面引入,只在组件定义的属性不生效,前面这里面没有定义autoPlay导致我的组件轮播不了,一度以为是swiper没有支持缩略图轮播
import { useRouter } from "vue-router";
const slides = reactive([
new URL("@/assets/images/1.png", import.meta.url).href,
new URL("@/assets/images/2.png", import.meta.url).href,
new URL("@/assets/images/3.png", import.meta.url).href,
new URL("@/assets/images/4.png", import.meta.url).href,
new URL("@/assets/images/5.png", import.meta.url).href,
new URL("@/assets/images/6.png", import.meta.url).href,
new URL("@/assets/images/7.png", import.meta.url).href,
new URL("@/assets/images/8.png", import.meta.url).href,
]);
const thumbsSwiper = ref<any>(null);
const setThumbsSwiper = (swiper: any) => {
thumbsSwiper.value = swiper;
};
const router = useRouter();
const toDetail = () => {
router.push("/detail");
};
</script>
<style scoped lang="less">
.swiper {
width: 100%;
height: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.swiper-slide img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
:deep(.swiper-button-prev, .swiper-button-next) {
color: #04af85;
}
:deep(.swiper-button-next) {
color: #04af85;
}
body {
background: #000;
color: #000;
}
.swiper {
width: 100%;
height: 300px;
margin-left: auto;
margin-right: auto;
}
.swiper-slide {
background-size: cover;
background-position: center;
cursor: pointer;
}
.mySwiper2 {
height: 80%;
width: 100%;
}
.mySwiper {
height: 20%;
box-sizing: border-box;
padding: 10px 0;
background-color: #000;
}
.mySwiper .swiper-slide {
width: 25%;
height: 100%;
opacity: 0.4;
}
.mySwiper .swiper-slide-thumb-active {
opacity: 1;
}
.swiper-slide img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
注:自己写的自动轮播效果
// 在topSwiper引入activeIndexChange选中时间方法
@activeIndexChange="resetTimer"
// 在topSwiper中获取实例
@swiper="setSwiper($event)"
const setSwiper = (swiperInstance: any) => {
swiperdata.value = swiperInstance
}
// 获取实例使用实例内嵌的slideTo方法切换
const goToNextSlide = () => {
if (swiperdata.value) {
const nextIndex = (swiperdata.value.activeIndex + 1) % slides.length // 获取当前页的下一个图片的索引
swiperdata.value.slideTo(nextIndex) // 选中当前页的下一个图片
}
}
//写的一个时间函数
const timer = ref<any>(null)
//在图片选中状态会移除,重新再生成一个,避免用户点击或者滑动查看某一项时间未重置的问题
const resetTimer = () => {
if (timer) clearInterval(timer.value)
timer.value = setInterval(() => {
goToNextSlide()
}, 5000)
}
//最后在页面挂载后调用 resetTimer()
效果图: