📌
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
프로젝트 진행 중 카테고리 부분을 구현하다가 슬라이드 기능을 넣고 싶어서 swiper를 사용했다.
내가 슬라이드 기능을 구현해야할 때마다 애용(?)하는 라이브러리이다.
가장 구현하기 쉽고 제공하는 형태도 다양해서 사용하기 좋다.
이번에 만들어 보면서 알게된 점이 단순하게 기본형태로도 만들 수 있지만 잘 이용하면 커스텀도 가능하고
반응형으로 만들 수 있다는 걸 알게되었다. 덕분에 구현하고 싶은 형태로 구현할 수 있었다.
공식 문서도 잘되어있지만 간단하게 사용하는 법을 써보자면,
설치하기
npm i swiper
사용하기
// 코어, 모듈 가져오기
import { Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules';
import { Swiper, SwiperSlide } from 'swiper/react';
// swiper 스타일 가져오기
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/scrollbar';
export default () => {
return (
<Swiper
// 필요한 모듈 설치
modules={[Navigation, Pagination, Scrollbar, A11y]}
spaceBetween={50} // 슬라이드 간의 간격
slidesPerView={3} // 한 화면에 보이는 슬라이드 개수
navigation // 네비게이션 설정
pagination={{ clickable: true }} // 페이지네이션 설정 및 클릭가능 여부 설정
scrollbar={{ draggable: true }} // 스크롤바 설정 및 드래그가능 여부 설정
onSwiper={(swiper) => console.log(swiper)} // 슬라이드 실행 시 함수
onSlideChange={() => console.log('slide change')} // 슬라이드 변경 시 함수
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
<SwiperSlide>Slide 4</SwiperSlide>
...
</Swiper>
);
};
기능중에 슬라이드 양옆에 버튼을 만들어 사용하는 네비게이션 기능을 구현하려고 하니
버튼이 너무 못생기기도 하고... 또, 이전, 다음 버튼의 위치를 바꾸고 싶기도 해서 커스텀 하는 법을 찾아봤다.
네비게이션 버튼 커스텀하기
간단한 형태로 보면,
import { Navigation } from 'swiper/modules';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
import 'swiper/css/navigation';
export default () => {
return (
<div>
<Swiper
modules={[Navigation]}
spaceBetween={50}
slidesPerView={3}
navigation
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
<SwiperSlide>Slide 4</SwiperSlide>
</Swiper>
<div>
<button>prev</button>
<button>next</button>
<div>
</div>
);
};
이렇게 만들어두고 각자 원하는 스타일로 스타일링하고 클릭 기능을 수행하는 함수를 만들어 주면 된다.
나는 이렇게 만들어줬다.
import { Swiper, SwiperClass, SwiperSlide } from "swiper/react";
import { Navigation } from "swiper/modules";
import "swiper/css";
import { FaArrowLeft, FaArrowRight } from "react-icons/fa";
import { useState } from "react";
type FiltersArray = {
filters: string[];
};
export default function FilterCategory({ filters }: FiltersArray) {
const [swiper, setSwiper] = useState<SwiperClass>();
const [activeFilter, setActiveFilter] = useState<number | null>(0);
const btnCustom = "p-2 rounded-full bg-gray-100 hover:brightness-90 absolute top-1/2 transform -translate-y-1/2";
const handlePrev = () => {
swiper?.slidePrev();
};
const handleNext = () => {
swiper?.slideNext();
};
const handleClickFilter = (index: number) => {
setActiveFilter(index);
};
return (
<div className="relative">
<Swiper
modules={[Navigation]}
navigation
slidesPerView={1}
onSwiper={e => {
setSwiper(e);
}}
className="relative w-8/12 gap-4 mb-4">
{filters.map((filter, index) => (
<SwiperSlide key={index}>
<button
onClick={() => handleClickFilter(index)}
className={`w-[150px] font-semibold p-2 rounded-full ${
activeFilter === index ? "bg-brand text-white" : "bg-gray-100 text-black"
}`}>
{filter}
</button>
</SwiperSlide>
))}
</Swiper>
<div>
<button onClick={handlePrev} className={`${btnCustom} left-2`}>
<FaArrowLeft />
</button>
<button onClick={handleNext} className={`${btnCustom} right-2`}>
<FaArrowRight />
</button>
</div>
</div>
);
}
아이콘을 사용해서 버튼을 만들고 싶었고 호버 효과도 주고 싶어서 스타일링을 따로 해줬다.
버튼 위치는 position 활용해서 슬라이드 양 옆에 위치하게 해줬다.
블로그글을 참고해서 각 버튼에 콜백함수를 만들어주고 타입오류는 SwiperClass를 사용해서 해결해줬다.
slidePrev, slideNext, SwiperClass 모두 swiper에서 제공하는 함수이다.
반응형으로 만들어 주기
일단 슬라이드를 만들고 나니 반응형으로 만들어야 하는 문제가 생겼다.
크기에 따라 보여주고 싶은 슬라이드개수가 달라지는데 이걸 어떻게 조건문을 만들어야되나.. .고민하던 와중에
swiper 자체에 breakpoins를 통해서 반응형을 만들 수 있다는 걸 알게되었다.
...
<Swiper
modules={[Navigation]}
navigation
slidesPerView={1} // 기본 설정은 모바일 크기부터
onSwiper={e => {
setSwiper(e);
}}
breakpoints={{
414: { // 414 이상일 경우
slidesPerView: 2,
},
768: { // 768 이상일 경우
slidesPerView: 3,
},
1024: { // 1024 이상일 경우
slidesPerView: 4,
},
1366: { // 1366 이상일 경우
slidesPerView: 6,
},
}}
className="relative w-8/12 gap-4 mb-4">
...
기본 설정은 모바일로 하고 크기 마다 한 화면에 보여지는 슬라이드 개수를 다르게 설정했다.
그동안 단순한 형태의 슬라이드 기능을 만들 때 사용하던 라이브러리 였는데 이렇게 본격적(?)으로는 처음 사용해본것 같다. 물론 이번에 만든것도 단순한 형태의 슬라이드이지만! 다음에는 더 화려하게 사용해보고 싶다.
📌 참고
'Front-end > React' 카테고리의 다른 글
[React] 리액트쿼리 useInfiniteQuery로 무한스크롤 구현하기 (0) | 2024.03.27 |
---|---|
[React] 리액트쿼리(React Query)란? (0) | 2024.03.25 |
[React] 모달창 구현 - 라이브러리 없이 구현하기 vs Chakra UI 사용하기 (0) | 2024.03.12 |
[React] Redux Middleware는 어떤 용도로 사용될까? (0) | 2024.01.18 |
[React] 상태관리 라이브러리 - zustand (0) | 2024.01.17 |