DEV Community

Cover image for A House is not a Home: Vue Slots Explained

Posted on

A House is not a Home: Vue Slots Explained

Cover from Design vector created by freepik -

Vue slots are a way of telling Vue where to place any content we write within a component's body. Today, we will be building houses to learn about Vue slots!

Before we begin, let's imagine Vue components as houses. For us to be able to enter a house, we would need to use a door; In our component, our <slot> tags would serve as a door for our other components to enter. Let's make our first house!

We use the slot element to tell our component where to display content. If we were to include our HouseComponent into a village component like so:

We see that our component placed all its child elements into the living room. Vue does this through the default slot.

Adding Rooms with Named Slots

Having a house with just a living room isn't a comfortable place to live in; let's introduce more rooms into our house component using named slots!

We can add the name attribute to our slots to, you guessed it, name them. This gives us the freedom to position parts of the content within our template.
Let's refactor our HouseComponent by adding more rooms and placing other elements within those rooms:

Let us notice two things about our new House:

First, we added a named slot called dining-room at line 8. To put content into this slot, we use the v-slot syntax in line 22. From here, we can see that chubbs and food are both placed between the two chairs in the dining-room: exactly where we placed our slot.

Second, everything else between the <house-component> tags that are not part of the named slots were rendered at the default slot, ie. within the living-room.

When this is rendered onto our page, it will look like this:

As we can see, we can use named slots to define layout for our markup. This makes components easy to compose and reuse. However, let's take it a notch higher, and introduce the concept of scoped slots to further improve our humble home.

Adding Furniture with Scoped Slots

Rooms in a house are not only defined by their position within the building, but also the activities that can be done within them! In the same way, Vue slots are not only a means of composing your components visually, but may also be used to expose interactions and data. This is done through scoped slots.

Components can bind data or methods to slots, like how they would with props. This allows the parent to interact with the component through the scoped slot. Let's add interactions to our HouseComponent to really call it a "home".

There are a few things we should dissect before moving on.
First, notice that we added v-bind directives to our named slots. These will allow the parent component to access anything bound to the slot as slot props. We added the <script> portion of the component to define our methods and data. Let's now add furnishings to our new home!

As we can see, we still use the v-slot syntax; however we appended a value to it. Each of our v-slots have access to different slot props, each containing the methods we bound to them in our HomeComponent. This means we can have different houses with different layouts, elements, contents, even components! Yet they all still have access to the functions of our HomeComponent; in our case, switching the channel, watching TV, and eating together.

Way Back Home

To conclude, we learned about Vue slots: how we can use named slots to lay out and compose our components (define our rooms), and how we can use scoped slots to expose functionality (add furniture).

I hope you found this article informative and easy to understand. Please do let me know if I have any errors in grammar or lapses in information that the reader would find helpful.

Thank you for reading, and good luck in building those houses!

Top comments (2)

alexparra profile image
Alex Parra

Nice write up Miguel!
I’ve recently had a situation where it would’ve come in handy the possibility of adding an event listener to a in order to catch events from slot components in the parent.
This is not possible unfortunately... maybe the awesome vue core team will add this sometime.