While I was trying to create my own carousel, I decided to use slots for this purpose.
I have two components: the main one is a carousel. vue and slide. vue. The carousel.vue stores all slides as slots.
What do I want? I want all slots which I add to my carousel that is a wrapper for all slides to display one at a time, so later I can add all functionality for my carousel
This is my carousel. vue
<template>
<div class="carousel">
<slot/>
</div>
</template>
<script>
</script>
This is my slide.vue
<template>
<div class="slide">
<slot/>
</div>
</template>
<script>
</script>
<template>
<Carousel>
<Slide>Image</Slide>
<Slide >Image</Slide>
<Slide >Image</Slide>
</Carousel>
</template>
<script setup>
import Carousel from "../../components/Reusable components/Carousel.vue"
import Slide from "../../components/Reusable components/Slide.vue"
</script>
<style>
</style>
Please, explain to me how to do it. I want to loop them with v-for but I don't know how to do it as long as I don't know how to create array for slides.
There are many ways to achieve, what you want to do. I will show you below an example (Simple) way to achieve what you want.
In your slide.vue, accept a prop
which is display a boolean
, based on which the slide will be displayed.
<template>
<div class="slide" v-if="display">
<slot />
</div>
</template>
<script setup>
defineProps({
display: {
type: Boolean,
default: false,
},
});
</script>
In your grandparent component, you can use a v-for to loop through the slides array. In my example, i have an array of objects in slides which i am looping through. You could have other content too.
Now i have the showslide
reactive ref whose initial value is 0 and i have added buttons to navigate through the slides by incrementing or decrementing. The display
prop will be true only when showslide === index
of the slides array.
<template>
<Carousel>
<div v-for="(slide, index) in slides" :key="index">
<Slide :display="showslide === index">{{ slide.content }}</Slide>
</div>
</Carousel>
<button @click="display = (display + 1) % slides.length">Next</button>
<button @click="display = (display - 1) % slides.length">Previous</button>
</template>
<script setup>
import Carousel from "@/components/Carousel.vue";
import Slide from "@/components/Slide.vue";
import { ref } from "vue";
const slides = [{ content: 1 }, { content: 2 }, { content: 3 }];
const showslide = ref(0);
</script>
<style></style>
So with this code, at first, the 0th slide will be shown and when you click next first slide and so on.
Hope it gives you an idea of how to achieve what you want.