Vue has support for slots built in and it is based on the shadow dom. It is a specification that is still in development but worth taking a look at to learn more about how they work, should this development approach become more common. Angular JS has a similar type of feature of content distribution which is referred to as transclusion. This tutorial will take a look at a few examples of slots in VueJS and how you can use them.
A Basic Slot Example
We’re starting out with a blank slate to start working with slots in VueJS. In our main App.vue file we just have a simple markup using Bootstrap’s flexbox abilities to center some text on the page. Simple stuff.
Create A SlotExample.vue file
We can create a slot example as a component in our project and place it in a components directory like so.
Let’s put the most basic of markup in this file like we have here.
The code above is not really using a slot per se, but it is a place where we can accept markup from another component to render inside the slot. Right now, we have the text of “Text In Slots Example” between the tags. What this means is that if we *don’t* pass any markup into the slot, then this text will be displayed by default.
Let us now import the SlotsExample.vue component into the App.vue file, register it, and make use of it.
Visiting our application in the browser shows this default text in action.
Content Distribution With Slots
Now check this out. We are going to make a change to the tag in App.vue. What we can do is actually put some html markup in between the tags. This markup will then be rendered in place of the tags in SlotExample.vue. Let’s see.
Now if we visit the browser, the markup is inserted where the tag was defined. Also note that the fallback text of “Text In Slots Example” is replaced entirely.
So in the most basic sense when you want to use slots in VueJS, you add the tags in the child component where you expect to receive data from outside. Slot is a reserved keyword in VueJs and as soon as it sees that markup, it does it’s thing to render the content that is being passed from the outside. In our case, we simply put an
Slot Styles and Compilation
In the App.vue file, we are passing as markup to be rendered in the of SlotExample.vue. It’s important to know where this code is compiled. We can check this using style rules. We can add some very basic styling in SlotExample.vue like so.
When we visit the browser now, we see that the color has changed.
What does this tell us? The child component’s style rules are applied to any data passed in from the outside when using a slot.
Now let’s change up what is in between the tags of App.vue. We will no longer hardcode a value, but we will use a data property to populate the markup like we see here.
Do you think this will still work? It looks like it does still work.
So for compiling the template, or in other words rendering any type of VueJS operation, the component where you actually have the code in the template will be the one doing the changes. So in our case, the root instance is the one doing the changes. Even though we are passing this data to the child using a slot, it is in this App.vue file’s template where the code is that takes precedence. The takeaway is that any styling is handled in the child component, where as everything else is taken care of in the parent component.
Named Slots In Vue
The slot tag can be used with a special attribute of name. This is a means to customize how the markup you define in slots gets distributed. This allows you to set up more than one slot since each can now be uniquely identified with the name attribute. In addition, you can still have a slot with no name, and that will act as the default case so to speak. Let’s see how this works.
Here we want to make use of more than one slot. By naming each slot, we now are able to do so. In the example markup below, we are saying that we are ready to accept markup from the outside via a slot which has a name of title, as well as a different slot with a name of body.
In the parent component, we now define these slots as we see. The h1 tag has an attribute, slot, which is set to title. The h3 tag has an attribute of slot set to body.
This is some body text son.
We can check it out in the browser and see each slot acting independently of each other thanks to those named slots.
Lets try something else now. In our example files, we can remove the slot with any references to “body”. Once we do this, we will have one named slot and another slot which is not named. See this markup.
This is some body text son.
In this case, VueJS will now treat the un-named slot as the default slot. What this means is that everything we are passing in which doesn’t have a named slot assigned, such as the h3 tag in our case, will get rendered in the default slot. The h1 tag with the slot name of “title” will get rendered in the while the h3 tag which has no slot name will get rendered in the default . When we look at it in the browser, this holds true.
There is also the concept of default content in slots. Let’s imagine we might have a subtitle slot but we are not sure if any sub title will be passed in. We want to display something if there is nothing passed in, but display what is passed in otherwise. We can set this up like so.
With just this markup, the result will look like this in the browser.
If we want to overwrite the default content in that named slot, we can do so. Here is add another slot in App.vue which specifies an h5 tag to be used as the sub title.
The Sub Title Passed In This is some body text son.
Now the result in the browser will use the data that is passed in, and not the text between the tags.
Vue Slots Tutorial Summary
Slots can be used to help you distribute your content in other components. It’s a new feature in web development, but may be quite useful for a variety of situations you might come across. Hopefully this tutorial sparks some ideas of how you might put them to work for you.