“ 당신은 소프트웨어 품질을 추구할 수도 있고, 포인터 연산을 할 수도 있다. 그러나 두 개를 동시에 할 수는 없다. ”
Swiper.js?
모바일 웹 개발에서 터치 슬라이더는 사용자 경험을 향상하는 핵심 요소 중 하나입니다. 그중에서도 Swiper 라이브러리는 뛰어난 성능과 다양한 기능으로 많은 개발자들에게 사랑받고 있습니다. 이번 포스팅에서는 Swiper 라이브러리의 기본 개념과 사용법에 대해 알아보겠습니다.
그러면 Swiper를 왜 사용하냐??
Swiper를 간단하게 설명해보자면 모바일 터치 슬라이더를 쉽게 구현할 수 있도록 도와주는 자바스크립트 라이브러리입니다. 뛰어난 터치 이벤트 처리와 애니메이션 효과를 지원하여, 다양한 모바일 디바이스에서 자연스러운 슬라이딩 기능을 구현할 수 있습니다.
Npm에서 설치 하는 방법
npm install swiper // 23.11월 기준 v11.0.4
CDN으로 설정하는 방법
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
Swiper 사용방법
현재 23년 11월 기준으로 swiper v11.0.4로 공식문서에서는 아직 swiper/react와 swiper/vue 등 리액트 및 뷰에 대한 모듈들을 간단하게 지원해 줬습니다. 그러나 이후 향후 버전에서는 제거될 가능성이 높다고 하여 swiper element로 마이그레이션 하는게 좋을 거 같다고 합니다.
저도 nuxt에서 swiper를 사용할때 vue awesome swiper 라이브러리를 자주 사용했습니다. 제공해 주는 swiper 컴포넌트를 사용해서 옵션 정도만 넣으면 간단하게 구성하기 편했으니까요! 그런데 아직은 사용할 수 있지만 향후 더 이상 유지하지 않는다고 공식문서에도 명시해 놨으니! swiper element로 사용하는 방법에 대해서만 간단하게 설명해볼까 합니다.
1. Swiper 모듈과 인스턴스 생성
import Swiper from 'swiper';
import { Navigation, Pagination } from 'swiper/modules';
// import Swiper and modules styles
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
// init Swiper:
const swiper = new Swiper('.swiper', {
// configure Swiper to use modules
modules: [Navigation, Pagination],
...
});
swiper element에서는 기본적으로 추가모듈 없이 핵심버전만 내보낸다고 합니다. 그래서 swiper/modules에서 사용하고자 하는 기능에 모듈을 불러와서 mdules에 설정해줘야 합니다. 저도 문서 대충 읽고 진행하다가 이거 못 봐서.. 왜 autoPlay 설정을 했는데 왜 재생이 안될까..? 엄청 고생했습니다! 역시 문서는.. 잘 읽어야겠죠..?
2. Swiper 옵션
모든 옵션에 대한 설명은 아니지만 그래도 자주 사용하는 옵션에 대해서 설명해 봤습니다 아래 내용을 참고하셔서 하나씩 연습해 보시는 걸 추천드려요!
import { Navigation, Pagination,Autoplay } from 'swiper/modules';
const swiper = new Swiper('.swiper-container',
{
// modules 기능은 여기에!
modules:[Autoplay,Navigation,Pagination],
// 슬라이더 방향 (가로: 'horizontal', 세로: 'vertical')
direction: 'horizontal',
loop: true, // 무한 루프
speed: 500, // 슬라이드 전환 속도 (ms)
centeredSlides: true // 가운데 설정
// 터치 및 드래그 관련 옵션
touchRatio: 1, // 터치 이벤트 민감도
grabCursor: true, // 마우스 커서를 슬라이더에 변경
// 뷰 설정
slidesPerView: 1, // 한 화면에 보여질 슬라이드 개수
spaceBetween: 10, // 슬라이드 간 간격 (px)
// 페이징 및 네비게이션
pagination: {
el: '.swiper-pagination',
clickable: true, // 페이징 클릭 가능 여부
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
autoplay:{ // 자동재생
delay: 3000, // 딜레이 시간
disableOnInteraction: false // 사용자 상호작용 후에도 자동 재생 유지
}
// 반응형 설정
breakpoints: {
// 화면의 크기
'@0.00': {
slidesPerView: 2.8, // 2.8개 슬라이드
spaceBetween: 10 // 간격10px
},
'@0.75': {
slidesPerView: 3.8,
spaceBetween: 10
},
'@1.00': {
slidesPerView: 3.8,
spaceBetween: 24
},
'@1.50': {
slidesPerView: 5.8,
spaceBetween: 24
}
}
})
3. Nuxt에서 실습
swiper에서 제공하는 css 말고 클래스를 추가해 간격을 조정하면서 예쁘게 만들어 보시면 될듯합니다.
아래 방법은 swiper-element 방법으로 인스턴스를 생성하여 옵션을 설정한 거이기 때문에 리액트는 다른 프레임워크에서도 같은 방식으로 사용하시면 됩니다.
여기서 dir속성에 ltr 또는 rtl은 문서의 텍스트 방향을 지정하는 속성 중에 하나입니다.
ltr은 left-to-right 약자로 왼쪽에서 오른쪽 방향으로 흐르고 rtl은 right-to-left 약자로 오른쪽에서 왼쪽 방향으로 슬라이더 방향을 지정할 수 있습니다. 자동재생으로 진행할 때 위에 속성은 유용하니 꼭 참고 바랍니다.
// 예시는 nuxt에서 설명합니다
<template>
<div class="swiper-wrap">
<div dir="ltr" class="swiper-container swiper-template">
<div class="swiper-wrapper">
<div
v-for="item in imgArray01"
:key="item.id"
class="swiper-slide"
>
<img :src="item.image" alt="" />
</div>
</div>
</div>
<div dir="rtl" class="swiper-container swiper-template">
<div class="swiper-wrapper">
<div
v-for="item in imgArray02"
:key="item.id"
class="swiper-slide"
>
<img :src="item.image" alt="" />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, nextTick, onMounted } from 'vue'
import Swiper from 'swiper'
import { Autoplay } from 'swiper/modules'
import 'swiper/swiper-bundle.css'
const imgArray01 = ref([
{
id: 1,
image: require('~/assets/images/01.webp')
}
])
const imgArray02 = ref([
{
id: 1,
image: require('~/assets/images/02.webp')
}
])
const options = ref({
modules: [Autoplay],
centeredSlides: true,
autoplay: {
delay: 0,
disableOnInteraction: false
},
speed: 20000,
loop: true,
autoHeight: true,
loopAdditionalSlides: 1,
breakpoints: {
'@0.00': {
slidesPerView: 2.8,
spaceBetween: 10
},
'@0.75': {
slidesPerView: 3.8,
spaceBetween: 10
},
'@1.00': {
slidesPerView: 3.8,
spaceBetween: 24
},
'@1.50': {
slidesPerView: 5.8,
spaceBetween: 24
}
}
})
const initializeSwiper = () => {
try {
swiper.value = new Swiper('.swiper-container', options.value)
} catch (error) {
console.error('Swiper initialization error:', error)
}
}
onMounted(() => {
nextTick(() => {
initializeSwiper()
})
})
</script>