Swiper.js 是一個功能齊全的輪播套件,除了輪播外,也可以客製化導航按鈕和頁碼等細項。目前支持 JS、React、Vue。我的 Vue3 專題中也有使用這套套件呈現,但因為 Swiper.js Vue 版是由 Composition API 寫成,但我當時只會 Options API,花了很多時間了解撰寫方式。今天目標就是介紹 Swiper.js 在 Vue3 Options API 的用法和元件化小撇步。

今日目標:Swiper 複用元件
目標功能
- 網頁每次顯示 3 則,768px 以下顯示 1 則
- 輪播時以更新 1 則為單位
- 可自動播放:Autoplay(自動播放)
- 可使用頁碼操作:Pagination(頁碼)
- 可使用導航切換上下頁:Navigation(上下一則導航)
- 輪播至最後一筆,會自動同方向重複播放:Loop(迴圈)
- 輪播元件可以重複使用,並秀出不同類別內容
一、官網資源/安裝
- Swiper 11:https://swiperjs.com/demos
Swiper 8:https://v8.swiperjs.com/vue- Swiper 4-7 中文翻譯(非官方):https://www.swiper.com.cn/api/scrollbar/369.html
--- 2024/04/08 更新:請裝這個 ------
npm i swiper@10.3.1
--- 舊文請忽略 ------
npm i swiper@8.0.0
是的沒錯~ 雖然現在 Swiper 版本已經是 11 了,但 Options API 在版本 8 才不會出錯(2024/04/08 更新:Swiper 10.3.1 也可以)。我的使用經驗是不管是否為同一個 swiper 元件,重複在同一個頁面使用沒有問題。但如果在不同頁面中使用,navigation(上/下一張)的導航就會失效,只有降版沒有問題,可能跟 Swiper 後期版本是用 Composition api 來撰寫有關。我個人是習慣各版本文件搭配著看,雖然中文翻譯版已經很舊了,但是初學時的好利器。實作時也推薦大家先從 11 的 Demos 尋找範例開始,比較好入手。
二、建立元件
1. 引入方法
建立元件文件 SwiperComponent.vue。
官網提到:By default Swiper Vue uses core version of Swiper (without any additional modules). If you want to use Navigation, Pagination and other modules, you have to install them first.
所以像是 Autoplay(自動播放)、Pagination(頁碼)、Navigation(上下一則導航)都是要額外引入的。
<script>
// import Swiper js
import { Swiper, SwiperSlide } from 'swiper/vue'
// Swiper 8 這樣寫 ↓
import { Autoplay, Pagination, Navigation } from 'swiper'
// Swiper 10 這樣寫 ↓
import { Navigation, Pagination, Autoplay } from 'swiper/modules'
// Import Swiper stylesimport 'swiper/css'
import 'swiper/css/pagination'
import 'swiper/css/navigation'
export default{
data () {
return {
data: ..., // 你要渲染的資料
modules: [Autoplay, Pagination, Navigation] // 額外引入的 modules
}
},
components: {
Swiper,
SwiperSlide
}
}
</script>
2. 撰寫 HTML
// swiper 輪播主體,設置都要在 Swiper 標籤範圍內才會生效
<Swiper
:slidesPerView="1"
:breakpoints="{
768: {slidesPerView: 3}
}"
:spaceBetween="30"
:pagination="{clickable: true,}"
:navigation="true"
:loop="true"
:autoplay="{
delay: 2500,
disableOnInteraction: false
}"
:modules="modules"
>
// 在 swiper-slide 裡面放入要呈現的圖片和標題,每個 swiper-slide 都是獨立的區塊
<swiper-slide v-for="item in data" :key="item">
<img :src="item.img" alt="item.title">
<h3>{{item.title}}</h3>
</swiper-slide>
</Swiper>

屬性說明:
- slidesPerView:每次輪播更換則數。
- breakpoints:RWD 響應式斷點,但是請注意只有文件中提到的屬性才能用 RWD,其他操作只能用 CSS 或 JS 實現。在這裡的設定是 slidesPerView 在 768px 以上顯示 3 則,以下顯示 1 則。
- spaceBetween:每則輪播間距,如果想做文字跑馬燈,也可以設定成 auto,讓他自動計算。
- pagination:在此設定為可以使用點選操作的,pagination 還有外觀選項。
- navigation:上下一則導航,如果要使用則設為 true,文章後面會再介紹如何客製化樣式。
- loop:播放至最後一筆時,能維持同一方向從第一筆繼續播放。如果不設定,則整個 swiper 會先逆向回到第一筆,才開始輪播。
- autoplay:自動輪播,在此設定 2500 毫秒輪播,滑鼠互動時,輪播不會暫停計秒。
詳細可以參考官方文件,內容有每個屬性的預設值和調整方法。
3. 在父元件使用
<template>
<div class="container"> // swiper 必須設定顯示區域尺寸
<SwiperComponent></SwiperComponent>
</div>
</template>
<script>
// 引入 swiper 元件
import SwiperComponent from '@/components/SwiperComponent.vue'
export default {
components: {
SwiperComponent
}
}
</script>
完成到這裡就可以使用啦!很方便又快速~
三、元件複用
1. 元件複用的好處
- 減少重複程式碼
- 調整只需要更動元件,避免修改四散的程式碼,較好維護
2. 實作方法
Vue 元件使用的資料可以由內部生成與外部傳入,我們要同時運用這兩個技巧。
- 先在 SwiperComponent.vue 中建立我們要顯示資料的欄位,以本文目標範例圖來說,首先是每個 swiper 區塊的標題。
我們先從父元件輸入外部資料試試看,於元件引用處上建立外部屬性 adCategoryTitle,並寫入要呈現的字串標題。
// 父元件
<template>
<div class="container">
<SwiperComponent adCategoryTitle="猜你喜歡吃甜甜"></SwiperComponent>
<SwiperComponent adCategoryTitle="邀請你來嚐口感"></SwiperComponent>
<SwiperComponent adCategoryTitle="美味氣氛隨你加"></SwiperComponent>
</div>
</template>
- 回到 swiper 元件,將剛才設定的外部屬性名稱填入,就完成了。
// SwiperComponent.vue
<template>
<div>
<h2>{{ adCategoryTitle }}</h2> // 使用資料
<Swiper...</Swiper>
</div>
</template>
<script>
export default {
... 略
props: ['adCategoryTitle'] // 由 props 接收外部傳入資料
}
</sctipt>
- 但通常複用元件不僅只有標題變化,輪播內容也要不同,所以我們可以再回頭修改上面的程式碼。
以下 swiper 元件運作邏輯是:
.將父元件傳入的文字屬性化,從中文標題改成分類。
.swiper 元件建立屬性對應的標題 adTitle,結合上一個步驟,就可以利用傳入資料對應獲取的中文標題了,這可以避免中文字要修改時父子元件都要更動的問題。
.父元件渲染時,每碰到 swiper 元件都會啟動mounted
獲取產品資料getProducts()
。
.getProducts()
也是根據外部傳入資料,獲取對應要顯示的產品內容。
// 父元件
<template>
<div class="container">
<SwiperComponent adCategoryTitle="sweet"></SwiperComponent>
<SwiperComponent adCategoryTitle="taste"></SwiperComponent>
<SwiperComponent adCategoryTitle="spices"></SwiperComponent>
</div>
</template>
// SwiperComponent.vue
export default {
props: ['adCategoryTitle'],
data () {
return {
allProducts: [],
adTitle: {
sweet: '猜你喜歡吃甜甜',
taste: '邀請你來嚐口感',
spices: '美味氣氛隨你加'
},
modules: [Autoplay, Pagination, Navigation]
}
},
methods: {
// 獲取產品
getProducts () {
if (adCategoryTitle === "sweet"){ // 根據傳入 props 獲取對應資料
...
this.allProducts = response
}else if (adCategoryTitle === "taste"){...}
}
},
mounted () {
this.getProducts()
},
components: {
Swiper,
SwiperSlide
}
}
</script>
四、客製化 swiper 樣式
1. 客製化 navigation
swiper 本身動作就綁定在原生 CSS 樣式上,不需要額外寫 id
或 class
使用 DOM
綁定。以下 .swiper-button-next
和 .swiper-button-prev
都是原生設定,藉由這兩項樣式調整 CSS,就可以客製化外觀了。
如果 navigation 要 RWD 響應式顯示,也是藉由 CSS 設定。
// SwiperComponent.vue
// 原本我們在 <Swiper> 標籤中的設定
<Swiper :navigation="true">
<SwiperSlide>...</SwiperSlide>
</Swiper>
// 修改成以下設定
<Swiper :navigation="{
nextEl: '.swiper-button-next', // 下一則
prevEl: '.swiper-button-prev' // 上一則
}">
<SwiperSlide>...</SwiperSlide>
// 因為要客製化 button,所以額外新增 DOM 在 <Swiper> 內,並套用原生 class 樣式
<button class="swiper-button-next"></button>
<button class="swiper-button-prev"></button>
</Swiper>
// SwiperComponent.vue
// 請依你的專案微調 css 數值
<style lang="scss" scoped>
// 替換成客製化 icon 的方法
.swiper-button-next{
// 插入你想使用的 icon 即設定尺寸
background: url("...") no-repeat center;
background-size: 40px 40px;
// 隱藏原生的藍色箭頭
text-indent: 101%;
white-space: nowrap;
overflow: hidden;
width: 40px;
height: 40px;
}
// 僅替換原生箭頭顏色的方法
.swiper-button-prev {
// 使用 color 就可以更換箭頭顏色
color: $red;
}
</style>
2. navigation 在 Swiper 元件範圍外顯示的方法
swiper 預設的 navigation 是在 .swiper
範圍內的。如果要讓 navigation(藍框)像下圖超出在 .swiper
(紅框)範圍外,我們要先來釐清它的 CSS。

swiper 結構
HTML 中 <Swiper>
生成的範圍就是途中右側使用 .swiper
樣式的區域範圍,它本身有 position-relative
和 overflow-hidden
的設定,所以我們可以發現:
- 查看 .
swiper-button-next
或.swiper-button-prev
,發現原生帶有position-absolute
樣式,所以可以透過top/right...
等方法定位。 - 如果直接移動
navigation
位置,會發現超出.swiper
的部分會被隱藏,所以我們要針對區域尺寸做更改。
// SwiperComponent.vue
<Swiper class="product-swiper"> // 新增一個樣式
...
</Swiper>
<style lang="scss" scoped>
// 由於我的預設是 768px 以內不顯示 navigation 所以做了 RWD 設定
// 如果 navigation 一直存在,只要參考 @media{} 內的程式碼就好
:deep(.product-swiper) {
margin: auto;
padding: 0;
@media (min-width: 768px) {
// 因為我的 navigation 尺寸是 40x40,我希望能凸出顯示一半,所以設定 20px
margin: 0 -20px !important;
padding: 0 20px !important;
}
}
</style>
我們可以從下圖理解 padding 和 margin 合作關係。
- 紅框是我們要限縮內容顯示的範圍
- padding 20px,將
.swiper
overflow-hidden
的範圍左右撐開 - margin -20px,讓輪播內容範圍內縮,如果不做這個設定,輪播範圍會跟黃框一樣

完成區塊設定後,再設定左右 navigaiton button 的位置就完成了~
<style lang="scss" scoped>
// 因為原生 swiper navigation 就帶有 position-absolute 樣式,所以直接定義位置
.swiper-button-next {
top: 50%;
right: 0px;
...
}
.swiper-button-prev {
top: 50%;
left: 0px;
...
}
</style>
3. 客製化 pagination
pagination 也可以使用原生的 .swiper-pagination
修改。
例如以下做了只有 768px 以下才顯示、更改 pagination 顏色。
/* swiper 顯示區域尺寸 */
// 其實 pagination 的位置是仰賴 swiper-wrapper 區塊
// pagintaion 預設自動貼合 swiper-wrapper 區塊底端,所以要藉由 margin-bottom 把區塊撐大
.swiper-wrapper {
margin-bottom: 36px;
@media (min-width: 768px) {
margin-bottom: 0rem;
}
}
/*Swiper 頁碼導覽*/
.swiper-pagination {
display: inline-block;
@media (min-width: 768px) {
display: none;
}
&-bullet {
background: #787878;
}
&-bullet-active {
background: #333333;
}
}