“ 당신은 소프트웨어 품질을 추구할 수도 있고, 포인터 연산을 할 수도 있다. 그러나 두 개를 동시에 할 수는 없다. ”
Swiper.js?
모바일 웹 개발에서 터치 슬라이더는 사용자 경험을 향상하는 핵심 요소 중 하나입니다. 그중에서도 Swiper 라이브러리는 뛰어난 성능과 다양한 기능으로 많은 개발자들에게 사랑받고 있습니다. 이번 포스팅에서는 Swiper 라이브러리의 기본 개념과 사용법에 대해 알아보겠습니다.
그러면 Swiper를 왜 사용하냐??
Swiper를 간단하게 설명해보자면 모바일 터치 슬라이더를 쉽게 구현할 수 있도록 도와주는 자바스크립트 라이브러리입니다. 뛰어난 터치 이벤트 처리와 애니메이션 효과를 지원하여, 다양한 모바일 디바이스에서 자연스러운 슬라이딩 기능을 구현할 수 있습니다.
Swiper - The Most Modern Mobile Touch Slider
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
swiperjs.com
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>