vue3 使用swiper輪播元件

齐行超發表於2024-10-22

1. 本地環境資訊參考

node版本:

nodejs : v18.20.4
npm : 10.7.0

vue版本

  "dependencies": {
    "vue": "^3.2.13",
    ...
  }

2. 安裝swiper依賴

執行命令:

npm i swiper

安裝後,檢視工程中的package.json檔案,新增了swiper依賴(預設最新版):

  "dependencies": {
    "swiper": "^11.1.14",
    "vue": "^3.2.13",
    ...
  }

3. 輪播圖預設效果

模擬輪播圖需求說明:

1、多張圖片,可自動播放
2、有指示器
3、有左右導航按鈕(向前、向後)

圖片匯入工程

程式碼實現 & 釋義:

匯入swiper元件:Swiper容器;SwiperSlide子項容器

import {Swiper, SwiperSlide} from 'swiper/vue';

匯入module:因為swiper將不同功能進行元件化拆分,使其更靈活化,我們使用具體的功能,只需匯入相應的module即可。
導航(左右按鈕功能)、Pagination(分頁指示器功能)、A11y (輔助功能模組,旨在提高網站或應用的可訪問性)、Autoplay(自動播放功能)

import {Navigation, Pagination, A11y, Autoplay} from 'swiper/modules';
const modules = [Navigation, Pagination, A11y, Autoplay]

匯入相關樣式,按功能匯入相應的css:

import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/autoplay';

template中使用Swiper、SwiperSlide元件,並配置module、屬性、事件等

<swiper
      class="swiper-container"
      :slides-per-view="1"
      :space-between="0"
      @swiper="onSwiper"
      @slideChange="onSlideChange"
      :modules="modules"
      :pagination="{ clickable: true }"
      :autoplay="{
      delay: 2000,
      disableOnInteraction: false,
      }"
      navigation
      :loop="true"
  >
    <swiper-slide>
      <img class="item" src="@/assets/banner/0.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/1.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/2.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/3.jpg"/>
    </swiper-slide>
  </swiper>

:slides-per-view: 這個屬性設定了每個滑塊(slide)的可見數量。在這裡,設定為 1 表示每次只顯示一個滑塊。
:space-between:這個屬性設定了滑塊之間的間距。在這裡,設定為 0 表示滑塊之間沒有間距。
@swiper="onSwiper":這個屬性是一個事件監聽器,當 Swiper 初始化完成時會觸發名為 "onSwiper" 的方法。
@slideChange="onSlideChange":這個屬性是另一個事件監聽器,當滑塊切換時會觸發名為 "onSlideChange" 的方法。
:modules:這個屬性指定了 Swiper 例項所使用的模組。透過這個屬性,可以配置 Swiper 例項使用的各種功能模組【此處配置了導航、指示器、自動播放等】。
:pagination:這個屬性配置了 Swiper 的分頁指示器,設定為可點選,使用者可以透過點選分頁器來切換到不同的滑塊。
:autoplay:這個屬性配置了自動播放功能,設定了播放延遲為 2000 毫秒(2秒),並且當使用者互動時不停止自動播放。
navigation:這個屬性開啟了 Swiper 的導航按鈕,通常會顯示左右箭頭或其他導航元素,用於使用者手動導航滑塊。
:loop:這個屬性設定了 Swiper 是否迴圈播放滑塊內容,即當滑動到最後一個滑塊時是否自動切換到第一個滑塊。設定為 true 表示開啟迴圈播放。

定義swiper例項,用於後續swiper操作,例如:跳轉下一頁、暫停自動播放等等

const swiperInstance = ref<typeof Swiper | null>(null);

事件方法定義

//初始化swiper後,為swiperInstance賦值
const onSwiper = (swiper: typeof Swiper) => {
  swiperInstance.value = swiper;
};
//監聽slide滑塊更改事件回撥
const onSlideChange = () => {
  console.log('slide change');
};
實現效果

完整程式碼參考
<template>
  <swiper
      class="swiper-container"
      :slides-per-view="1"
      :space-between="0"
      @swiper="onSwiper"
      @slideChange="onSlideChange"
      :modules="modules"
      :pagination="{ clickable: true }"
      :autoplay="{
      delay: 2000,
      disableOnInteraction: false,
      }"
      navigation
      :loop="true"
  >
    <swiper-slide>
      <img class="item" src="@/assets/banner/0.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/1.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/2.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/3.jpg"/>
    </swiper-slide>
  </swiper>
</template>
<script lang="ts" setup>
import {ref} from 'vue';
import {Swiper, SwiperSlide} from 'swiper/vue';
import {Navigation, Pagination, A11y, Autoplay} from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/autoplay';

const modules = [Navigation, Pagination, A11y, Autoplay]
const swiperInstance = ref<typeof Swiper | null>(null);

const onSwiper = (swiper: typeof Swiper) => {
  swiperInstance.value = swiper;
};
const onSlideChange = () => {
  console.log('slide change');
};
</script>

<style scoped>
.swiper-container {
  background-color: white;
}

.item {
  width: 100%;
  height: auto;
}
</style>

4. 最佳化自動播放效果

如果使用者滑鼠移入swiper,應該讓swiper暫停滑動,方便使用者檢視當前滑塊的具體資訊;如果滑鼠滑出swiper,應該繼續自動滑動。

實現:

swiper ui元件監聽滑鼠移入、移出事件:

@mouseenter="pauseSwiper"
@mouseleave="resumeSwiper"

script程式碼中,實現對應的方法:

const pauseSwiper = () => {
  if (swiperInstance.value) {
    swiperInstance.value.autoplay.stop();
  }
};
const resumeSwiper = () => {
  if (swiperInstance.value) {
    swiperInstance.value.autoplay.start();
  }
};

5. 自定義左右導航按鈕

多數情況下,需要參考專案的UI設計稿,調整左右導航按鈕效果/樣式。

此處,我們模擬修改下,使用兩張圖片作為左右導航按鈕。

script中,先實現左右切換滑塊的功能:

const goPrev = ()=> {
  if (swiperInstance.value) {
    swiperInstance.value.slidePrev();
  }
};
const goNext = () => {
  if (swiperInstance.value) {
    swiperInstance.value.slideNext();
  }
};

swiper ui元件上不再配置預設的navigation屬性。
匯入按鈕圖片:

佈局中新增左右按鈕,並設定其樣式:

  <div class="custom-navigation">
      <img src="@/assets/img_pre.png" class="custom-swiper-button-prev" @click="goPrev">
      <img src="@/assets/img_next.png" class="custom-swiper-button-next" @click="goNext">
  </div>

.custom-swiper-button-prev, .custom-swiper-button-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  color: #FFFFFF;
  font-size: 20px;
  width: 50px;
  height: 50px;
}

.custom-swiper-button-next {
  right: 20px;
}

.custom-swiper-button-prev {
  left: 20px;
}

自定義導航按鈕效果:

完整程式碼

<template>
  <swiper
      class="swiper-container"
      :slides-per-view="1"
      :space-between="0"
      @swiper="onSwiper"
      @slideChange="onSlideChange"
      :modules="modules"
      :pagination="{ clickable: true }"
      :autoplay="{
      delay: 2000,
      disableOnInteraction: false,
      }"
      :loop="true"
      @mouseenter="pauseSwiper"
      @mouseleave="resumeSwiper"
  >
    <swiper-slide>
      <img class="item" src="@/assets/banner/0.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/1.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/2.jpg"/>
    </swiper-slide>
    <swiper-slide>
      <img class="item" src="@/assets/banner/3.jpg"/>
    </swiper-slide>
  </swiper>
  <div class="custom-navigation">
      <img src="@/assets/img_pre.png" class="custom-swiper-button-prev" @click="goPrev">
      <img src="@/assets/img_next.png" class="custom-swiper-button-next" @click="goNext">
  </div>
</template>
<script lang="ts" setup>
import {ref} from 'vue';
import {Swiper, SwiperSlide} from 'swiper/vue';
import {Navigation, Pagination, A11y, Autoplay} from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/autoplay';

const modules = [Navigation, Pagination, A11y, Autoplay]
const swiperInstance = ref<typeof Swiper | null>(null);

const onSwiper = (swiper: typeof Swiper) => {
  swiperInstance.value = swiper;
};
const onSlideChange = () => {
  console.log('slide change');
};

const pauseSwiper = () => {
  if (swiperInstance.value) {
    swiperInstance.value.autoplay.stop();
  }
};
const resumeSwiper = () => {
  if (swiperInstance.value) {
    swiperInstance.value.autoplay.start();
  }
};
const goPrev = ()=> {
  if (swiperInstance.value) {
    swiperInstance.value.slidePrev();
  }
};
const goNext = () => {
  if (swiperInstance.value) {
    swiperInstance.value.slideNext();
  }
};
</script>

<style scoped>
.swiper-container {
  background-color: white;
}

.item {
  width: 100%;
  height: auto;
}

.custom-swiper-button-prev, .custom-swiper-button-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  color: #FFFFFF;
  font-size: 20px;
  width: 50px;
  height: 50px;
}

.custom-swiper-button-next {
  right: 20px;
}

.custom-swiper-button-prev {
  left: 20px;
}
</style>

相關文章