I'm having a bit of trouble working out how to use slots for a SliderA component.
SliderA component looks like the following with slides
being an array prop.
<template>
<div class="slider-container" ref="container">
<div class="viewport" ref="viewport">
<div class="slider" ref="slider">
<div v-for="(slide, index) in slides" :key="index" class="slide">
<slot :name="`example-${slide._id}`"></slot>
</div>
</div>
</div>
</div>
</template>
And on the page itself I am doing the following:
<SliderA :slides="data.homePage.featuredGenres">
<template v-for="genre in data.homePage.featuredGenres" v-slot:[`example-${genre._id}`] :key="genre._id">
<div class="genre">
...
</div>
</template>
</SliderA>
This seems to be working but I have a few concerns.
It breaks if I put the :key on the <div class="genre"></div>
element within the template loop. The error states the key must be placed on the template tag. Confusing.
I am passing in the data (an array of objects) to the component as a prop :slides="data.homePage.featuredGenres"
in order to loop through the slots within the component which feels unnecessary but can't work out another way to do it.
UPDATE
I tried the following which seems to work but feels like there's a simpler way. Plus, the CSS within the component don't render (or flash off) on load. I think this would require a minimal reproduction but might just have to try and make it less efficient.
<SliderA :slides="data.homePage.featuredGenres">
<template v-for="genre in data.homePage.featuredGenres" v-slot:[`example-${genre._id}`] :key="genre._id">
<GenreItem :genre="genre" />
</template>
</SliderA>
You need scoped slots (you pass data to the slot from its component).
And read documentation for key
in v-for
.
You use a default slot here, no need in named slots.
#="{slide: genre}"
here is a shortcut for <template v-slot="{slide: genre}">
for the default slot.
<script setup>
import SliderA from './SliderA.vue';
const data = {
homePage:{
featuredGenres: [{name: 'Trash metal'}, {name: "Drum'n'bass"}]
}
};
</script>
<template>
<SliderA :slides="data.homePage.featuredGenres" #="{slide: genre}">
<div class="genre">
{{ genre.name }}
</div>
</SliderA>
</template>
SliderA.vue
<script setup>
defineProps({
slides: Array
})
</script>
<template>
<div class="slider-container" ref="container">
<div class="viewport" ref="viewport">
<div class="slider" ref="slider">
<div v-for="(slide, index) in slides" :key="index" class="slide">
<slot :="{slide}"></slot>
</div>
</div>
</div>
</div>
</template>