# Nuxt3 Swiper 運用
## 套件安裝
```
npm i swiper
```
## [Swiper 縮圖圖庫(Thumbs gallery)](https://swiperjs.com/)
版本:swiper 11.2.6
本案例擁有展示圖及所有圖片縮圖,並另外設置上下張圖片切換鈕可自行擺放按鈕位置
:::spoiler 結果示意圖

:::
### 程式碼
```htmlembedded=
<template>
<template v-if="data">
<div class="showBox">
<swiper
:style="{
'--swiper-navigation-color': '#fff',
'--swiper-pagination-color': '#fff',
}"
:spaceBetween="10"
:navigation="{
nextEl: '.nextBtn',
prevEl: '.prevBtn',
}"
:thumbs="{ swiper: thumbsSwiper }"
:modules="modules"
class="mySwiper2"
@swiper="onSwiper"
@slideChange="onSlideChange"
>
<template v-for="(item, index) in data">
<swiper-slide class="imgBlack">
<div class="imgBox">
<img width="1290.59" height="667.109" :src="item" :alt="'展示圖檔_' + (index + 1)" loading="lazy"/>
</div>
</swiper-slide>
</template>
</swiper>
</div>
<div class="switchBtnBox">
<div class="prevBtn" :class="{'noPrev' : currentSlideIndex == 0}">上一張</div>
<div class="nextBtn" :class="{'noNext' : currentSlideIndex == (data.images?.length - 1)}">下一張</div>
</div>
<div class="thumbnailBox">
<swiper
@swiper="setThumbsSwiper"
:spaceBetween="10"
:slidesPerView="setSlidesPerView"
:freeMode="true"
:watchSlidesProgress="true"
:modules="modules"
class="mySwiper"
>
<template v-for="(item, index) in data">
<swiper-slide class="imgBlack">
<img width="114.594" height="185.594" :src="item" :alt="'燈箱選擇圖檔_' + (index + 1)" loading="lazy" />
</swiper-slide>
</template>
</swiper>
</div>
</template>
</template>
<script setup>
import { Swiper, SwiperSlide } from 'swiper/vue';
import { FreeMode, Navigation, Thumbs } from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/free-mode';
import 'swiper/css/navigation';
import 'swiper/css/thumbs';
import { onMounted } from 'vue';
const modules= [FreeMode, Navigation, Thumbs]
// swiper套件連動 縮圖及顯示圖片
const thumbsSwiper = ref(null)
const setThumbsSwiper = (swiper) =>{
thumbsSwiper.value = swiper
}
const currentSlideIndex = ref(1);
const swiperInstance = ref(null);
// 當 Swiper 初始化時,儲存 Swiper 實例
const onSwiper = (swiper) => {
swiperInstance.value = swiper;
currentSlideIndex.value = swiper.activeIndex; // 設置初始索引
};
// 當輪播切換時,更新當前索引
const onSlideChange = (swiper) => {
currentSlideIndex.value = swiper.activeIndex;
};
// 設置縮圖顯示幾張
const setSlidesPerView = ref(6)
if(data.value?.length){
if(data.value?.length >= 6){
setSlidesPerView.value = 6
} else {
setSlidesPerView.value = data.value?.length || 6
}
}
// 測試檔案
const data = ref([
"https://picsum.photos/id/222/1200/600",
"https://picsum.photos/id/223/1200/600",
"https://picsum.photos/id/214/1200/600",
"https://picsum.photos/id/225/1200/600",
"https://picsum.photos/id/216/1200/600",
"https://picsum.photos/id/227/1200/600",
"https://picsum.photos/id/228/1200/600",
"https://picsum.photos/id/229/1200/600"
])
const switchImg = (index) =>{
if(!index) retrun;
if (swiperInstance.value) {
swiperInstance.value.slideTo(imgIndex, 300); // 切換主輪播到該索引,300ms 動畫
}
if (thumbsSwiper.value) {
thumbsSwiper.value.slideTo(imgIndex, 300); // 同步縮圖輪播
}
}
</script>
<style lang="scss">
// 文字設置
@mixin fontStyle($font_fontWeight, $font_fontSize, $lineHeight: 1.5) {
font-weight: $font_fontWeight;
font-size: $font_fontSize;
line-height: $lineHeight;
}
@mixin Body_R_16() {
@include fontStyle(400, 1.6rem);
}
// 色彩設置
$switchBtnTextColor:rgba(59, 54, 53, 1);
$switchBtnDisabledTextColor:rgba(119, 119, 119, 1);
// 主要樣式設置
.showBox{
width: 100%;
aspect-ratio: 990/580;
display: flex;
justify-content: center;
align-items: center;
@media screen and (max-width: 960px){
aspect-ratio: 375/220;
}
.mySwiper2{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.imgBlack{
display: flex;
justify-content: center;
align-items: center;
.imgBox{
width: 100%;
height: 100%;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
img{
display: block;
width: 100%;
height: 100%;
// object-fit: contain;
object-fit: cover;
}
}
}
}
}
.switchBtnBox{
width: 100%;
position: relative;
display: flex;
justify-content: flex-end;
column-gap: 2rem;
margin-top: 2.1rem;
margin-bottom: .7rem;
@media screen and (max-width: 960px){
display: none;
}
.nextBtn,
.prevBtn{
cursor: pointer;
width: max-content;
color: $switchBtnTextColor;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
@include Body_R_16();
&.noPrev,
&.noNext{
color: $switchBtnDisabledTextColor;
cursor: not-allowed;
}
}
}
.thumbnailBox{
width: 100%;
@media screen and (max-width: 960px){
padding-left: 2rem;
}
.mySwiper{
width: 100%;
height: 100%;
.imgBlack{
img{
display: block;
width: 100%;
height: 100%;
object-fit: contain;
cursor: pointer;
}
}
}
}
</style>
```
##### 參考資料
[參考網址:swiper官網 範例](https://swiperjs.com/demos)