🛝

SwiperをReactで実装

2023/12/24に公開

概要

Slideを実装する時、Web制作をしていた昔はjQueryでslickなどを利用して作っていました。

今回、要件的にReactで実装する必要があったので良いライブラリはないかなと探していたところ、Swiperという老舗のライブラリを見つけ使ってみたところ、かなりいろんなバリエーションにも対応しているので参考になるかと思い、記事を書くことにしました。

使い勝手が良いライブラリなので、Slideを作りたい方は検討の際の参考にしていただければと思います。

使い方

インストール

npm i swiper

基本スライダーを追加する

公式を使って単純なスライダーを作りました。

app.tsx
import "swiper/css";
import { Swiper, SwiperSlide } from "swiper/react";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
        slidesPerView={3}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
      >
        {data.map((d) => (
          <SwiperSlide>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
      </Swiper>
    </>
  );
}

export default App;

これだけのコードで基本的なスライダーができました。

ページネーションを追加する

ページネーションを追加していきます。
モジュールに追加する必要があります。

app.tsx
import "swiper/css";
+ import { Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
        slidesPerView={3}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
+        modules={[Pagination]}
+        pagination={{
+          type: "fraction",
+        }}
      >
        {data.map((d) => (
          <SwiperSlide>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
      </Swiper>
    </>
  );
}

export default App;

これだけでページネーションが追加されました。

次へ/前へボタンを用意する

hooksが用意されています。
https://swiperjs.com/react#useswiper

このhooksの中で次へ遷移するボタンの挙動を追加することができます。
ボタンのコンポーネントを作成し、画面に表示してみます。

SlideNextButton.tsx
import { useSwiper } from "swiper/react";

export const SlideNextButton = () => {
  const swiper = useSwiper();

  return <button onClick={() => swiper.slideNext()}>Next</button>;
};
SlidePrevButton.tsx
import { useSwiper } from "swiper/react";

export const SlidePrevButton = () => {
  const swiper = useSwiper();

  return <button onClick={() => swiper.slidePrev()}>Prev</button>;
};
app.tsx
import "swiper/css";
import { Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
+ import { SlideNextButton } from "./components/SlideNextButton.tsx";
+ import { SlidePrevButton } from "./components/SlidePrevButton.tsx";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
        slidesPerView={3}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
        pagination={{
          type: "fraction",
        }}
        modules={[Pagination]}
      >
        {data.map((d) => (
          <SwiperSlide>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
+        <div>
+          <SlidePrevButton />
+          <SlideNextButton />
+        </div>
      </Swiper>
    </>
  );
}

export default App;

非常に簡単に付けれました。

1ページに1枚表示にし次の画像をチラ見せする

ページの真ん中にアクティブのスライドを表示するようにし、ページの中に表示される枚数を2にします。

app.tsx
import "swiper/css";
import { Pagination } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import { SlideNextButton } from "./components/SlideNextButton.tsx";
import { SlidePrevButton } from "./components/SlidePrevButton.tsx";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
+        centeredSlides={true}
-        slidesPerView={3}
+        slidesPerView={2}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
        pagination={{
          type: "fraction",
        }}
        modules={[Pagination]}
      >
        {data.map((d) => (
          <SwiperSlide>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
        <div>
          <SlidePrevButton />
          <SlideNextButton />
        </div>
      </Swiper>
    </>
  );
}

export default App;

そうすると、画像のようにアクティブスライドが真ん中にいきました。
右には少しだけ次の画像が見えるようになっています。
ページネーションも自動で4枚分に分かれるようになりました。
Nextを押した場合も適用されています。

マウスで動かせるようにする

上記だと、ボタンを押さないと次のスライドに移動しません。戻る時も同じです。
これをマウスでドラッグするだけで次のスライドに移動させるようにします。

app.tsx
import "swiper/css";
- import { Pagination } from "swiper/modules";
+ import { Pagination, Mousewheel } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import { SlideNextButton } from "./components/SlideNextButton.tsx";
import { SlidePrevButton } from "./components/SlidePrevButton.tsx";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
        centeredSlides={true}
        slidesPerView={2}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
        pagination={{
          type: "fraction",
        }}
-        modules={[Pagination]}
+        modules={[Pagination, Mousewheel]}
      >
        {data.map((d) => (
          <SwiperSlide>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
        <div>
          <SlidePrevButton />
          <SlideNextButton />
        </div>
      </Swiper>
    </>
  );
}

export default App;

モジュールを追加しただけで、マウスで操作ができるようになりました。
素晴らしすぎです。
特別なことは何もしてません。

Cubeとかの変更にしてみよう

app.tsx
import "swiper/css";
+ import "swiper/css/effect-cube";
- import { Pagination, Mousewheel } from "swiper/modules";
+ import { Pagination, Mousewheel, EffectCube } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import { SlideNextButton } from "./components/SlideNextButton.tsx";
import { SlidePrevButton } from "./components/SlidePrevButton.tsx";

const data: string[] = ["Slide 1", "Slide 2", "Slide 3", "Slide 4"];

function App() {
  return (
    <>
      <Swiper
        spaceBetween={50}
        centeredSlides={true}
        slidesPerView={2}
        onSlideChange={() => console.log("slide change")}
        onSwiper={(swiper) => console.log(swiper)}
        pagination={{
          type: "fraction",
        }}
-        modules={[Pagination, Mousewheel]}
+        modules={[Pagination, Mousewheel, EffectCube]}
+        effect="cube"
      >
        {data.map((d) => (
          <SwiperSlide key={d}>
            <div style={{ background: "grey", height: "300px" }}>{d}</div>
          </SwiperSlide>
        ))}
        <div>
          <SlidePrevButton />
          <SlideNextButton />
        </div>
      </Swiper>
    </>
  );
}

export default App;

これもモジュールを読み込むだけです。
めちゃくちゃ楽ですね。

こんな感じでキューブを回転させる感じでスライドさせることができます。

基本、モジュールとCSSを読み込むだけで使えます。
非常に使いやすいです。

この他にも以下のようなエフェクトがあります。

  • Fade
  • Cube
  • Coverflow
  • Flip
  • Cards
  • Creative

参考: https://swiperjs.com/react#effects

まとめ

お手軽にスライダーを作れるライブラリSwiper/reactでした。
まだまだいっぱいモジュールや機能、レイアウトの変更やイベントの検知などがあるので、随時追記していけたらと思います。

是非、スライダーを実装する際には検討材料にしてみてください。

Discussion