When we’re building a front end app with Vue.js, there are several ways to communicate between our parent and child components. Besides props, of which we’ve already talked about, one of the most common ways to pass top – to -bottom data are slots.

In case you haven’t heard of them, slots are a way to pass HTML from a parent component to a child component in Vue.js. This allows us to create reusable components that can be customized according to the needs of the individual developer.

Slots are a great way to create flexible and versatile components, but they’re not without their own set of challenges. In this article, we’ll take a look at what slots are and how they work, some of the pros and cons of using them, and work with a few examples. Let’s get started!

What is exactly a slot?

A slot is an area in a component where you can pass HTML from a parent component. This can be very useful in certain situations, such as when you want to create a reusable component that can be customized depending on a specific use case.

For example, let’s say we have a component that renders a list of tasks:

<template>
  <Task v-for="task in tasks"></Task>
</template>

<script>
import Task from "./components/Task.vue";
export default {
  components: {
    Task,
  },
  data() {
    return {
      tasks: [
        {
          id: 1,
          title: "Task 1",
        },
        {
          id: 2,
          title: "Task 2",
          comment: "This task is completed",
        },
        {
          id: 3,
          title: "Task 3",
        },
      ],
    };
  },
};
</script>

The tasks themselves will have a section where comments might be added; but this area will only be visible in some tasks and not others.

One way to ensure we’re only showing this comment section would be to pass down a “comment” object via slots. This way, too, we can reuse this component for different types of tasks, even if some of them don’t have any kind of comment section at all.

In our parent component, we’ll only need to pass our comment like this. For comparison, we’re also passing down our task title as a prop:

<template>
  <Task v-for="task in tasks" :title="task.title">
    <p>{{ task.comment }}</p>
  </Task>
</template>

Here’s what our child component would look like in this scenario:

<template>
  <h2>{{ title }}</h2>
  <slot></slot>
</template>

<script>
export default {
  props: ["title"],
};
</script>

And the end result would resemble something like this:

As you can see, only our second task is displaying a comment paragraph. Notice that we didn’t need to use any kind of conditional rendering tool like v-if or v-show.

Types of slots

In Vue.js, there are basically two types of slots:

  • Named slots.
  • Default slots.

Let’s take a deeper look at each of them.

1- Named slots

Named slots allow you to insert HTML into a specific area of the component. For example, if you have a component with a header, sidebar, and content area, you can use named slots to insert HTML into each one of those areas specifically.

This is very useful when we want to have different slot sections in a singular component, something that would be tricky otherwise. Named slots are declared using the slot name attribute on the child component:

<slot name="firstSlot"></slot>

And then passing our HTML from our parent component like this:

<ChildComponent>
   <template v-slot:firstSlot>
     <p>Custom First</p>
   </template>
</ChildComponent>

2- Default slots

Default slots, on the other hand, do not have a name attribute. Default slots are used when you want to be able to insert HTML into a specific part of a component but don’t know exactly what your use case will be.

Default slots are simply declared by using the slot element on the child component. And in order to pass our HTML, we don’t need to add anything special in our parent component.

Are slots really useful?

Some developers argue that there are not many cases where slots might be useful. However, others find them to be incredibly handy in a number of situations.

Here are some examples where slots can be very helpful:

  • Passing static content to a child component. You can use slots to pass static content like texts, images, and links to a child component. This is especially useful if the child component is reusable and you want to avoid duplicating the static content in multiple places.
  • Passing dynamic content to a child. Similar to the previous use case, you can also use slots to pass dynamic content like user input or data from an API call to a child component. This allows the child component to be more flexible and customizable.
  • Styling a child component. By inserting your own HTML into the child component, you can override its default styles and give it your own custom styling.

In conclusion, slots are a powerful feature in Vue.js that allows you to customize further your components and that help you pass data between different parts of your application in a pretty straightforward way.

We hope you found this article helpful! Any questions you might have, feel free to leave a comment and we’ll do our best to answer it.

👋 Hey, I'm Alejandro Rodríguez
Hey there! I'm a front end developer from Spain and a web dev teacher at Ironhack. I've been writing for more than 7 years as a side project, and I love to mix both disciplines whenever I can. Besides working, I'm also passionate about travelling (often with my laptop as a digital nomad) and water sports. What could be better than writing about code in a Caribbean beach, or from a coworking space in an european city?

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.