Introduction
Recently, I started learning VueJS, and this article is part of the series of my notes while learning it. In this post, I will cover a feature I like a lot in Vue, slots. I already covered how you can pass data to the components using the props, but slots allow us to pass custom templates. This might sound weird at first, but think of something like the modal. Every modal usually has a backdrop, and content container but the content inside can be different. You don’t want to create a full modal every time, and slots help us to do that in a more reusable way.
Initial component
I will not go into too many details when it comes to the initial component. Let's just assume we have one, the PopUpMessage component, to which we will pass some content it will display. For simplicity, I will not add any show-and-hide logic to it.
Simple Usage
First, we need to add some code to our PopUpMessage component so that it knows where it will render your content. We do that by adding the slot tag inside of its template.
<template>
<div>
<div>PopUp Message</div>
<slot></slot>
</div>
</template>
Now that we defined where content is going to be rendered, we need to pass it. In the simplest version, all we need to do is place content between the opening and closing tags of the component.
<PopUpMessage>
Content
</PopUpMessage>
Passing using the template tag
An alternative way to achieve the same as above is to use a template tag and add the v-slot directive to it.
<PopUpMessage>
<template v-slot>Content</template>
</PopUpMessage>
At this moment you might be looking at the code above and think that we achieved the same result as before. But with more complexity. And you would be right, however, the usage above does have its benefit. And that is named slots.
Named slots
I am repeating myself. Passing templates is a very useful feature and enables us to build more reusable code. But what when we need to pass multiple separate templates? Think again of our PopUpMessage component. Passing content is great, but what if we want to customize the header as well? We could pass one big content containing both, but maybe a better option would be passing them separately so that the PopUpMessage component can place them in the appropriate place. The first step to do this is to update the PopUpMessage component.
<div>
<div>
<slot name="header"></slot>
</div>
<slot></slot>
</div>
If we run the previous usage of this component, just content will be shown. So we need to also add some code that will pass the header template. We do that by adding another template and adding a slot name after the v-slot directive.
<PopUpMessage>
<template v-slot:header>PopUp message header</template>
<template v-slot>Content</template>
</PopUpMessage>
Named slot shorthand
Vue also supports shorthands for the v-slot directive, and it is done by using the hash sign and name of the slot after it. For the unnamed slot, we use the name default.
<PopUpMessage>
<template #header>PopUp message header</template>
<template #default>Content</template>
</PopUpMessage>
Conclusion
There are many more features and benefits of the slots. But I hope that from this short post, you got enough introduction to understand what they are. And in the next post, I will cover things like scoped slots.
The code used in this article can be found in my GitHub repository.
For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.