I'm creating my own carousel where images are added by <img>. I think that the method of creating carousel component in vue is way more flexible because I want to add inside LightBox component inside my carousel's slots
This is my parent component carousel
<template>
<div class="carousel">
{{ slides }}
<slot></slot>
</div>
</template>
<script>
import { ref } from 'vue';
export default{
data(){
return{
Currentslide: 0,
}
},
setup(props, {slots}){
const slides=ref(slots.default().map((slides) => slides.props.id))
return{
slides,
}
}
}
</script>
This is my child component slide
<template>
<div class="slide">
<slot/>
</div>
</template>
<script>
</script>
<template>
<Carousel>
<Slide id="1">1243423</Slide>
<Slide id=2>
1231
</Slide>
<Slide id="3">r445</Slide>
</Carousel>
</template>
<script>
import Carousel from "../../components/Reusable components/Carousel.vue"
import Slide from "../../components/Reusable components/Slide.vue"
export default{
components:{
Carousel,
Slide
}
}
Using the inefficient method in the world, I somehow can create an array of slots' indexes. But this is the worst solution to this problem. So, I want to explore another way of extracting IDs from slots in Vue.js
Do you really need slots? It can be done much simpler, I guess.
const { createApp } = Vue;
const MyImg = {
props: ['src'],
template: '<img :src="src" class="image" />'
}
const MyGallery= {
components: { MyImg },
props: ['images'],
data() {
return {
current: 0
}
},
methods: {
prev() {
this.current--;
if (this.current < 0) this.current = this.images.length - 1;
},
next() {
this.current++;
if (this.current > this.images.length -1) this.current = 0;
}
},
template: '#my-gallery'
}
const App = {
components: { MyGallery },
data() {
return {
images: [
'https://images.unsplash.com/photo-1517423568366-8b83523034fd?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80',
'https://images.unsplash.com/photo-1609910063430-33fc20be9f88?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80',
'https://images.unsplash.com/photo-1576138089064-2ca7edab2f49?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80',
'https://images.unsplash.com/photo-1612637306950-fd33786d912e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=300&q=80'
]
}
}
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
label { font-weight: bold; }
.container {
min-height: 320px;
}
.image {
max-width: 300px;
max-height: 300px;
position: absolute;
}
.slide-left-enter-active,
.slide-left-leave-active {
transition: all 0.3s ease-out;
}
.slide-left-enter-from {
opacity: 0;
transform: translateX(150px);
}
.slide-left-leave-to {
opacity: 0;
transform: translateX(-150px);
}
<div id="app">
<div class="container">
<my-gallery :images="images">
</my-gallery>
</div>
<p>Pictures © Unsplash</p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script type="text/x-template" id="my-gallery">
<button @click="prev()"><</button> Bild {{current + 1}}
<button @click="next()">></button>
<br />
<transition-group name="slide-left">
<my-img v-for="(img, index) in images" v-show="current == index" :key="index" :src="img">
</my-img>
</transition-group>
</script>