Slots
Share:
In VueJS, Slots are a powerful feature that allows for the creation of reusable and flexible components. They enable us to inject content in different parts of a child component from a parent component, something that is powerfully illustrative of Vue's component-based approach.
Understanding Slots
To put it simply, a slot is a placeholder in a component where you can inject any content you want. These placeholders can be defined in the child component and are then filled from the parent component.
Let's consider a basic Vue application with a parent component called 'MovieListing' and a child component named 'MovieCard'.
In this scenario, the MovieCard component is used within the MovieListing component, and each item in the MovieListing component needs to have a specific title and description, both of which are unique values. This is where slots can come in handy.
<template>
<div class="movie-card">
<h2>Movie Name</h2>
<p>Some movie description here...</p>
</div>
</template>
<script>
export default {
name: 'MovieCard',
}
</script>
In the 'MovieCard' component above, we have hardcoded the movie name and description. But suppose we want to reuse this 'MovieCard' component in our 'MovieListing' component, each with a different movie name and description. In that case, we can replace the hardcoded values with something more dynamic like slots.
Here's how you can change the 'MovieCard' component to include slots:
<template>
<div class="movie-card">
<h2><slot name="movieTitle">Default Movie Title</slot></h2>
<p><slot name="movieDescription">Default Movie Description</slot></p>
</div>
</template>
In the template section above, notice the special <slot>
HTML tags. These tags represent slots that you can fill with your content from a parent component ('MovieListing'). Each slot has a unique attribute called name
which helps differentiate slots from one another. The text inside the slot tag, like "Default Movie Title" or "Default Movie Description", is used as a fallback content in case no content is injected into the slot from a parent.
Filling Slots from Parent Component
Like our 'MovieListing' component, a parent component must have the required parameters in order to fill these slots in the child component. It should look something like this:
<template>
<div>
<h1>Movie Listing</h1>
<MovieCard>
<template v-slot:movieTitle>
<div>Harry Potter and the Philosopher's Stone</div>
</template>
<template v-slot:movieDescription>
<div>A young wizard begins his magical journey at Hogwarts School of Witchcraft and Wizardry.</div>
</template>
</MovieCard>
</div>
</template>
<script>
import MovieCard from "@/components/MovieCard.vue";
export default {
components: {
MovieCard
}
};
</script>
In the parent 'MovieListing' component, we're using the <template>
tag to specify content for the designated slots we have in the 'MovieCard' child component. The directive v-slot
is used to indicate the name
of the slot we're filling. Now the values we pass in the 'MovieListing' component will replace the slots in the 'MovieCard' component.
Remember, you must register the 'MovieCard' in components section of 'MovieListing' component.
Default Slots
In VueJS 2.6.0, a new feature was added: scoped slots. These slots allow you to pass data from the child component back to the parent. For example, if your component generates a list of movies and you want to give the parent component access to the individual movie object, you can use scoped slots.
Here's an example of a scoped slot in the child component:
<template>
<div class="movie-card">
<slot movie="movie">
<h2>{{ movie.title }}</h2>
<p>{{ movie.description }}</p>
</slot>
</div>
</template>
<script>
export default {
props: ['movie']
};
</script>
In the parent component, you now have access to the movie prop and can use it within the slot.
<template>
<div>
<MovieCard v-for="movie in movies" :movie="movie" :key="movie.id">
<template v-slot:default="props">
<h2>{{ props.movie.title }}</h2>
<p>{{ props.movie.description }}</p>
</template>
</MovieCard>
</div>
</template>
<script>
import MovieCard from "@/components/MovieCard.vue";
export default {
components: {
MovieCard
},
data() {
return {
movies: [
{ id: 1, title: 'Movie 1', description: 'Awesome movie' },
{ id: 2, title: 'Movie 2', description: 'Even better movie' },
]
}
}
};
</script>
Slots are a powerful VueJS feature that makes our components more flexible and reusable. There is a lot more to slots, like slot composition or dynamic slots, but for the sake of simplicity, we’ve just scratched the surface. Happy coding!
0 Comment
Sign up or Log in to leave a comment