VueT2 Light_1200x303

Slots in Vue are extremely versatile once you know how to use them. Let’s get to know them by building a sandwich. 

Vue <slot> is one of the most powerful tools there is in terms of component composition. Slots allow you to inject any type of content into a component, provide a default value, and even expose data from a child component to a parent.

The learning curve, however, can be a little daunting. Let’s take a closer look at slots together.

Slot, Ya Basic

In Vue we have two different “kinds” of slots. The regular simple slot, and the more complex scoped slot. In order to fully understand the scoped slots, we need to first get a nice grasp on the simple ones.

Ya basic

Let’s get into the mood. Forget about Vue for a second, and let’s talk basic HTML. It doesn’t get any simpler than a <p> tag, so let’s look at that.

<p>The cake is a lie, except when it's not. Then you nom. You NOM hard.</p>

Take a good look at this example. You have a <p> tag with some content in between. We can even make it a little more “interesting” (😴), by adding a nested tag. Let’s go with a <span>.

<p>
	The cake is a lie, except when it's not. Then you nom. 
	<span class="seriousNomming">You NOM hard.</span>
</p>

If I told you to tell me what’s happening in here, you would probably describe it as a tag that has some content. Right? And the <p> tag itself has a defined behavior. We know as frontend programmers that the <p> tag will usually display as a block element with some predefined margins. It has some properties and predefined behavior.

An Example Component

Sweet, now let’s switch gears and think in terms of components. Consider the following example.

<Sandwich>
	<Avocado />
	<Cheese />
	<Ham />
</Sandwich>

If once again we tried to describe what’s happening here, we could easily say that there is a Sandwich component that is going to display an 🥑, 🧀 and 🐷. How exactly do we create such a component though? How do we tell it: Hey, I want you (Sandwich) to be able to hold any sort of ingredients/content.

Such a component would be written in this fashion:

// Sandwich.vue

<template>
  <div class="bread">
    <slot/>
  </div>
</template>

<style>
.bread {
  border-top: 3px solid brown;
  border-bottom: 3px solid brown;
}
</style>

Awesome! Now if you actually use this component with the previous example, you will get a desired (but ultimately ugly, don’t judge me) result, as follows.

<Sandwich>
    🥑
    🧀
    🐷
</Sandwich>

Where exactly is the magic happening in terms of Vue?

The <slot> reserved component exposes a space where the component will render any input that it is given. ANY input. That means you can put text, HTML elements, and even other components inside of the <Sandwich> tags, and everything will be passed down to the component. Neat, right?

There’s an important thing to consider: a component can actually have more than one <slot> element! We will look at an example soon, but how does it know right now which one to use?

The default behavior for <slot> tags it as a default slot. This means that just writing <slot /> actually means <slot name="default" />

Default Slot Content

There are two things we want to touch up on here—default content and additional slots. Let’s look at default content first.

If we wanted to make our default sandwich be an avocado-only sandwich, we could make a small change to our component as follows.

<template>
  <div class="bread">
    <slot>
      🥑
    </slot>
  </div>
</template>

See how there’s now some default content in between the <slot> tags? This will become the default content for this slot. What this means is that if someone was to implement a Sandwich component without any content, they will get an avocado in the output.

<Sandwich /> // Will display 🥑 between the "bread"

Named Extra Slots

Another powerful feature that Vue gives us with slots is named slots. Sometimes you will find yourself in a situation where you want to be able to give the user of your component the ability to display custom content on several different places of your component.

In such cases, named slots are your friend. Consider our sandwich example. Maybe you want to be able to expose a slot on top of the bread that will allow for some grilling options.

Our component after some minor tweak will look like this.

<template>
  <div>
    <slot name="grilling"></slot>
    <div class="bread">
      <slot>🥑</slot>
    </div>
  </div>
</template>

Notice how our new slot element has the attribute of name set to grilling. This name is the reference that people using our component will call when adding content to that particular part of it. Keep in mind that you can add as many named slots as you need. Also, the same rules apply—named slots can have default content of their own.

Now, to actually put this new slot into use, we have to use a special syntax inside the parent component that is instantiating the <Sandwich>. You will add a new <template> element inside the component declaration, and add a v-slot:<slotName> property to it, where slotName is the name that we defined earlier in our component definition.

<Sandwich>
  <template v-slot:grilling>🧀🧀🧀</template>
	🥑
    🧀
    🐷
</Sandwich>

This component will now have three servings of cheese on top of the bread! 🤤

For extra information on slots check out the official documentation.

Wrapping up

Understanding the first steps of slots inside Vue opens up the door for a ton of possibilities in regard to component composition. In the next part of this article, we will look at the more advanced side of slots: the scoped slot.

The code examples for this article can be found in the following sandbox: https://codesandbox.io/s/first-look-at-vue-slots-it3xv.

As always, thanks for reading and share with me your basic slot experiences on Twitter at: @marinamosti.

P.S. All hail the magical avocado! 🥑

P.P.S. ❤️🔥🐶☠️


Marina Mosti_2020
About the Author

Marina Mosti

Marina Mosti is a full-stack web developer with over 13 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue, as well as writing articles and tutorials for the community.

She currently holds a position as Lead FE Developer at VoiceThread, and she is the author of the FormVueLatte library as well as a member of the Vuelidate team. In her spare time, she enjoys playing bass, drums, and videogames.

Related Posts

Comments

Comments are disabled in preview mode.