프로젝트

[프로젝트] Next.js에서 Swiper 적용하기

ejunyang 2024. 7. 31. 20:08

🔗 swiper API

 

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

 

 

 


 

 

설치

yarn add swiper

 

 

Import

8버전 이하는 import의 경로가 다를 수 있으니 확인해봐야한다. 가장 최신 버전은 아래와 같다.

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

 

module import

import { Pagination } from 'swiper/modules';
더보기
  • Virtual - 가상 슬라이드 모듈
  • Keyboard - 키보드 제어 모듈
  • Mousewheel - 마우스 휠 제어 모듈
  • Navigation - 내비게이션 모듈
  • Pagination - 페이지네이션 모듈
  • Scrollbar - 스크롤바 모듈
  • Parallax - 패럴렉스 모듈
  • FreeMode - 자유 모드 모듈
  • Grid - 그리드 모듈
  • Manipulation - 슬라이드 조작 모듈 (코어 버전 전용)
  • Zoom - 확대 모듈
  • Controller - 컨트롤러 모듈
  • A11y - 접근성 모듈
  • History - 히스토리 내비게이션 모듈
  • HashNavigation - 해시 내비게이션 모듈
  • Autoplay - 자동 재생 모듈
  • EffectFade - 페이드 효과 모듈
  • EffectCube - 큐브 효과 모듈
  • EffectFlip - 플립 효과 모듈
  • EffectCoverflow - 커버플로우 효과 모듈
  • EffectCards - 카드 효과 모듈
  • EffectCreative - 크리에이티브 효과 모듈
  • Thumbs - 썸네일 모듈

css import

// Import Swiper styles
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/scrollbar';
더보기
  • swiper/css/a11y - 접근성 모듈에 필요한 스타일
  • swiper/css/autoplay - 자동 재생 모듈에 필요한 스타일
  • swiper/css/controller - 컨트롤러 모듈에 필요한 스타일
  • swiper/css/effect-cards - 카드 효과 모듈에 필요한 스타일
  • swiper/css/effect-coverflow - 커버플로우 효과 모듈에 필요한 스타일
  • swiper/css/effect-creative - 크리에이티브 효과 모듈에 필요한 스타일
  • swiper/css/effect-cube - 큐브 효과 모듈에 필요한 스타일
  • swiper/css/effect-fade - 페이드 효과 모듈에 필요한 스타일
  • swiper/css/effect-flip - 플립 효과 모듈에 필요한 스타일
  • swiper/css/free-mode - 자유 모드 모듈에 필요한 스타일
  • swiper/css/grid - 그리드 모듈에 필요한 스타일
  • swiper/css/hash-navigation - 해시 내비게이션 모듈에 필요한 스타일
  • swiper/css/history - 히스토리 모듈에 필요한 스타일
  • swiper/css/keyboard - 키보드 모듈에 필요한 스타일
  • swiper/css/manipulation - 조작 모듈에 필요한 스타일
  • swiper/css/mousewheel - 마우스 휠 모듈에 필요한 스타일
  • swiper/css/navigation - 내비게이션 모듈에 필요한 스타일
  • swiper/css/pagination - 페이지네이션 모듈에 필요한 스타일
  • swiper/css/parallax - 패럴렉스 모듈에 필요한 스타일
  • swiper/css/scrollbar - 스크롤바 모듈에 필요한 스타일
  • swiper/css/thumbs - 썸네일 모듈에 필요한 스타일
  • swiper/css/virtual - 가상 모듈에 필요한 스타일
  • swiper/css/zoom - 확대 모듈에 필요한 스타일

 

컴포넌트

export default () => {
  return (
    <Swiper
      spaceBetween={50}
      slidesPerView={3}
      onSlideChange={() => console.log('slide change')}
      onSwiper={(swiper) => console.log(swiper)}
    >
      <SwiperSlide>Slide 1</SwiperSlide>
      <SwiperSlide>Slide 2</SwiperSlide>
      <SwiperSlide>Slide 3</SwiperSlide>
      <SwiperSlide>Slide 4</SwiperSlide>
      ...
    </Swiper>
  );
};

 

옵션

modules={[Pagination, Autoplay]} : 사용할 모듈

spaceBetween : 슬라이드 사이 간격(margin)
slidesPerView : 보여질 슬라이드 수
centeredSlides: 센터 모드
pagination={{ clickable: true }} : 페이지네이션 버튼을 눌렀을 때 이동 가능
navigation : Prev, Next 버튼
autoplay={{ delay: 2000, disableOnInteraction: false }} : 자동 재생 / 지연시간 / 사용자 상호작용시 슬라이더 일시 정지 비활성
loop={true} : 반복여부

 

 

프로젝트 적용

스타일은 tailwind css를 사용하고 있어서 global.css에 최소한의 스와이퍼 슬라이드 스타일을 적용해줬다. 페이지네이션(인디케이터)에 스타일을 적용해줘야했기때문도 있다 ㅎ 의문점은 페이지네이션 스타일을 페이지마다 다르게 할 순 없을까..? 모듈로 들어가 있어서 스타일을 어떻게 먹여줘야할지 잘모르겠다.

/* 슬라이드 공통 css */
.swiper {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: left;
  border-top-right-radius: 12px;
  border-top-left-radius: 12px;

  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}

.swiper-slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.swiper-pagination {
  width: 164px !important;
  background-color: rgba(232, 193, 142, 0.64) !important;
  border-radius: 8px;
  padding: 5px 20px;
}

.swiper-horizontal > .swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal {
  left: 50% !important;
  transform: translateX(-50%);
}

.swiper-pagination-bullet-active {
  background-color: rgb(117, 84, 40) !important;
  width: 64px !important;
  border-radius: 4px !important;
}

.swiper-pagination-bullet {
  background-color: rbg(189, 135, 63) !important;
}

 

 

SwiperSlide

메인 페이지 시장 섹션은 슬라이드로 구현되어야했기 때문에 아래와 같이 사용해보았다.

 {images?.slice(0, 4).map((item, index) => (
        <SwiperSlide key={index} className="!w-[311px]">
          <div>
            {item.이미지 ? (
              <Image
                src={`${item.이미지[0]?.link}`}
                width={454}
                height={340}
                priority
                alt={`Slide ${index + 1}`}
                style={{
                  height: 340,
                  border: '3px solid #9C6D2E',
                  borderTopLeftRadius: '12px',
                  borderTopRightRadius: '12px'
                }}
              />
            ) : (
              <>없음</>
            )}
          </div>
          <div className="bg-primary-20 text-label-light p-4 rounded-br-[12px] rounded-bl-[12px]">
            <div className="flex justify-between items-center">
              <h2 className="text-lg font-semibold">{item.시장명}</h2>
              <LikeButton />
            </div>
            <div className="text-sm mt-2 leading-[22.4px]">
              <p>{item['시장 유형']}</p>
              <p>{item.도로명주소}</p>
            </div>
          </div>
        </SwiperSlide>

 

 

 

완성

메인에 시장섹션뿐만 아니라 배너에도 사용했고, 특산물 상세페이지의 상단 이미지도 슬라이드로 구현했다!