Understanding how to use Slots

Slots is an important part of Vue. They make it possible to compose your components in a semantic way and the parent component can easily control what's inside.


A component without slots

Here is an example of how a component can be built without using slots.

Vue.component('business-card', {
    props: ['name'],
    template: `
        <div class="card">
            <h2>{{ name }</h2>
        </div>
    `
})

How to use it.

<business-card name="Vue Hero" />

With a slot
Here is the same example but now we are going to use a single slot.

Vue.component('business-card', {
    template: `
        <div class="card">
            <h2><slot></slot></h2>
        </div>
    `
})

How to use it.

<business-card>Vue Hero</business-card>

The slot-element inside the business card component tells Vue that everything that is put between <business-card></business-card> should be placed there. That can be text and it can be HTML, whatever suits your needs!


A component with named slots

A great thing about the Slots is that you can add names to them and you can add as many slots as you like. Here is an example of a component with three different slots.

Vue.component('business-card', {
    template: `
        <div class="card">
            <h2><slot></slot></h2>

            <strong>Title: </strong><slot name="title"></slot><br>
            <strong>Phone: </strong><slot name="phone"></slot>
        </div>
    `
})

How to use it.

<business-card>
    <span slot="title">Website</span>
    <span slot="phone">+123 123 123</span>
    Vue Hero
</business-card>

As you see here you can combine named slots with an unnamed one which will be the default slot. It's not just the content inside <span slot="title"></span> that will be passed into the component, it's the whole element. If you right click on the code and inspect it in your browser, you will see.

Here is the same example on CodePen. Click on Run Pen to test if and if you want to make some changes you can click the "Edit on CodePen" button to the right.

See the Pen Multiple named slots by Vue Hero (@vuehero) on CodePen.


Slots with html

Here is an example where we pass in a whole block of HTML into the component.

Vue.component('modal-wrapper', {
    template: `
        <div class="modal-wrapper">
            <div class="content">
                <slot></slot>
            </div>

            <footer>
                This is the contents of the footer inside the modal wrapper
            </footer/>
        </div>
    `
})

How to use it.

<modal-wrapper>
    <div>
        <h2>Vue Hero</h2>

        <strong>Title: </strong>Website<br>
        <strong>Phone: </strong>+123 123 123
    </div>
</modal-wrapper>

If you test this in your browser you will see that the code you add inside <modal-wrapper></modal-wrapper> will be added inside the content of the modal-wrapper. I added a default wrapper to the modal-wrapper just so you could see that there can be other code there too.

See the Pen Slots with html by Vue Hero (@vuehero) on CodePen.


Slots with default content

Often we want to create a component with a default value and only change the value when we write something in the slot. Here is an example of how to do that.

Vue.component('business-card', {
    template: `
        <div class="card">
            <slot>No content yet. This text will be replaced by whatever you add inside the component tag.</slot>
        </div>
    `
})

How to use it.

<business-card />

Since we added text inside the slot tag when we created the component and added nothing inside the <business-card /> tag the default text will be showing. This can be great if you want default placeholder text or something like that.


<router-link> is just a component with a slot

If you have used Vue Router you have definitely come over <router-link>. Here is a way you can set up your own link component like the <router-link>.

Vue.component('my-link', {
    props: ['href', 'classname'],
    template: `
        <a :href="href" :class="classname">
            <slot></slot>
        </a>
    `
})

Here we create a new component named my-link. We make it possible to pass in the two properties href and class. Inside the template, we bind the two properties to the link's attributes and inside the link we create an unnamed slot. Avoid using names like "class" as a property name because this conflicts with Vue. So, in this case, we call the variable "classname" instead.

Here is how you can use this:

<my-link href="https://vuehero.com" classname="blue-link">Vue Hero</my-link>

Here is the example in CodePen:

See the Pen Custom link component by Vue Hero (@vuehero) on CodePen.

Summary

That was my way of explaining how Vue Slots are working. I hope you found it useful and that you now know a little bit more about how to implement them into your projects. Knowing how the Slots are working is important to know how some parts of Vue are working. Take the <router-link> for example. If you implement that on your site and there is an error, you might be able to easier understand what's wrong now that you know how it's built.