🤔

Vue 3で複数Swiperをpropsで個別制御(JSONデータ版)

に公開

公式の Vue 用コンポーネントもあるけれど、細かく制御したいときや、軽く導入したいケース、雛形だけ作って、親側で諸々調整したい、ので自作コンポーネント化しておく。

環境

  • Vue 3
  • TypeScript
  • Swiper v11(swiper@latest)

props で ID(クラス名)やタイトルを受け取って流用できる Swiper コンポーネント

SwiperComponent.vue
<template>
  <div>
    <h2>{{ title }}</h2>
    <div :class="['swiper', swiperId]">
      <ul class="swiper-wrapper">
        <li v-for="(item, i) in items" :key="i" class="swiper-slide">
          {{ item.name }}
        </li>
      </ul>

      <div :class="`swiper-button-prev ${swiperId}`"></div>
      <div :class="`swiper-button-next ${swiperId}`"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import Swiper, { Navigation } from 'swiper';
import 'swiper/css';
import 'swiper/css/navigation';
import { onMounted } from 'vue';

const props = defineProps<{
  swiperId: string,
  title: string,
  items: { title: string }[]
}>();

onMounted(() => {
  const el = document.querySelector(`.${props.swiperId}`) as HTMLElement;
  if (!el) return;

  new Swiper(el, {
    loop: true,
    modules: [Navigation],
    navigation: {
      nextEl: `.${props.swiperId}-next`,
      prevEl: `.${props.swiperId}-prev`
    }
  });
});
</script>

<style scoped>
.swiper {
  width: 100%;
  height: auto;
}
.swiper-slide {
  background: #eee;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  font-weight: bold;
}
</style>

使い方

jsonから取り出した情報でスライダーを作る。

App.vue
<template>
  <div>
    <SwiperComponent
      v-for="(slider, i) in sliders"
      :key="i"
      :swiperId="slider.id"
      :title="slider.title"
      :items="slider.items"
    />
  </div>
</template>

<script setup lang="ts">
import SwiperComponent from './components/SwiperComponent.vue';
import data from './data/sliders.json';

const sliders = data.sliders;
</script>
sliders.json
{
  "sliders": [
    {
      "id": "slider1",
      "title": "スライダー1",
      "items": [
        { "name": "スライド1-1" },
        { "name": "スライド1-2" },
        { "name": "スライド1-3" }
      ]
    },
    {
      "id": "slider2",
      "title": "スライダー2",
      "items": [
        { "name": "スライド2-1" },
        { "name": "スライド2-2" },
        { "name": "スライド2-3" }
      ]
    }
  ]
}

ポイント

  • JSONにタイトルとスライド配列をまとめる
  • 親でv-forして複数Swiperを生成
  • ナビボタンもswiperIdで個別制御

これで親側にスライダーが2個あってもスライダーがそれぞれ独立して動作、jsonで取り出したデータでスライダーを作ることができます。
jsonデータの取り出しわけも親側で制御すればいい感じになるかなと思います。

Discussion