Vue 3(composition API)でカルーセルスライダーを作る方法
Vue.js V3(composition API)でカルーセルスライダーを作る方法を紹介します。
バニラJavaScriptでスライダーを作成する場合は、JavaScriptのスライダーのコードも参考にしてみてください。
Vue 3(composition API)でカルーセルスライダーを作る方法
ディレクトリ構成
root
├─ src
├─ App.vue
├─ main.js
├─ assets
│ └─ img
│ └─ 画像たち
├─ components
│ ├─ Carousel.vue
│ ├─ CarouselSlide.vue
今回触るのは、
- App.vue
- Carousel.vue
- CarouselSlide.vue
の3つです。
App.vue
template
<div class="app">
<Carousel
@next="next"
@prev="prev"
>
<CarouselSlide
v-for="(slide, index) in slides"
:key="slide"
:index="index"
:visibleSlide="visibleSlide"
>
<img :src="slide"/>
</CarouselSlide>
</Carousel>
</div>
まず、親コンポーネントであるApp.vueでは、2つのコンポーネントを入れ子にします。
Carouselからは、nextとprevというボタンのクリックイベントを受け取ります。
CarouselSlideでは、画像データをv-forでループして、表示できるようにpropsを渡します。
渡すものは、index番号と、現在表示しているものの番号です。
script
import Carousel from './components/Carousel.vue'
import CarouselSlide from './components/CarouselSlide.vue'
import { ref, computed } from 'vue'
export default {
name: 'App',
components: {
Carousel,
CarouselSlide,
},
setup() {
const slides = ref([
'画像',
'画像',
'画像',
...,
])
// indexとイコールの変数を作成する
const visibleSlide = ref(0)
const slidesLength = computed(() => slides.value.length)
// Carouselから受け取ったnext
const next = () => {
if(visibleSlide.value >= slidesLength.value - 1) {
visibleSlide.value = 0
} else {
visibleSlide.value++
}
}
// Carouselから受け取ったprev
const prev = () => {
if(visibleSlide.value <= 0) {
visibleSlide.value = slidesLength.value - 1
} else {
visibleSlide.value--
}
}
return {
slides,
visibleSlide,
next,
prev,
}
}
}
まず、コンポーネントをインポートします。
そして、refとcomputedを使うので、それらもインポートします。
そして、画像データをrefで登録して、リアクティブにします。
そのデータの数を取得しておきたいので、computedでLengthを計算した値を格納する変数を用意しておきます。
また、現在のスライドを示す変数も用意しておきます。
そして、Carousel.vueから受け取ったnextとprevというメソッドを設定します。
インデックス番号がデータの数、つまり画像数を表すので、それで条件分岐します。
最初か最後の場合と、そうでない場合で分岐して、
最初の場合は最後へ、最後の場合は最初へ移動するようにします。
最初か最後出ない場合は、1ずつ増やす、減らすという設定をすればいいです。
Carousel.vue
template
<div class="carousel">
<slot></slot>
<button @click="next" class="carousel__next">次へ</button>
<button @click="prev" class="carousel__prev">前へ</button>
</div>
App.vueへ渡したいnextとprevメソッドを設定します。
script
export default {
setup(props, context) {
const next = () => {
context.emit('next')
}
const prev = () => {
context.emit('prev')
}
return {
next,
prev,
}
}
}
Vue 3で親コンポーネントへイベントやデータを渡したい場合、つまりemitしたい場合、setup(props,context)の2つ目の引数であるcontextを使います。
context.emit(eventName)を実行することで、親コンポーネントへ渡すことができます。
CarouselSlide.vue
template
<div v-show="visibleSlide === index" class="carousel-slide">
<slot></slot>
</div>
親から受け取ったpropsを使います。
表示したいものは現在のスライドで、それはindexと同じものとすればOKです。
script
export default {
props: [
'visibleSlide',
'index',
]
}
受け取るためのpropsを設定すればOKです。