Vue.js 2 Slots
Slots help you position content in a component, and allow parent components to arrange it.
A component can be 100% responsible for generating its output, like in this case:
Vue.component('user-name', {
props: ['name'],
template: '<p>Hi {{ name }}</p>'
})
or it can also let the parent component inject any kind of content into it, using slots.
What is a slot? It’s a space in your component output that is reserved, waiting to be filled.
You define a slot by putting <slot></slot> in a component template:
Vue.component('user-information', {
template: '<div class="user-information"><slot></slot></div>'
})
When using this component, any content added between the opening and closing tag will be added inside the slot placeholder:
<user-information>
<h2>Hi!</h2>
<user-name name="Flavio"></user-name>
</user-information>
If you put any content side the <slot></slot> tags, that serves as the default content in case nothing is passed in.
A complicated component layout might require a better way to organize content, with multiple slots as well.
This is why Vue offers us named slots.
Named slots
With a named slot you can assign parts of a slot to a specific position in your component template layout, and you use a slot attribute to any tag, to assign content to that slot.
Anything outside any template tag is added to the main slot.
For convenience I use a page single file component in this example:
<template>
<div>
<main>
<slot></slot>
</main>
<aside>
<slot name="sidebar"></slot>
</aside>
</div>
</template>
Here is how we can use it, providing the slots content, in a parent component:
<page>
<template v-slot:sidebar>
<ul>
<li>Home</li>
<li>Contact</li>
</ul>
</template>
<h2>Page title</h2>
<p>Page content</p>
</page>
There is a handy shorthand, #:
<page>
<template #sidebar>
<ul>
<li>Home</li>
<li>Contact</li>
</ul>
</template>
<h2>Page title</h2>
<p>Page content</p>
</page>
Note: Vue 2.6 deprecated the
slotattribute in favor ofv-slot, and requires it to be added to atemplatetag (whileslotcould be applied to any tag)
Scoped slots
In a slot, we can’t access the data contained in the child component from the parent.
Vue recognizes this use case and provides us a way to do so:
<template>
<div>
<main>
<slot v-bind:dogName="dogName"></slot>
</main>
</div>
</template>
<script>
export default {
name: 'Page',
data: function() {
return {
dogName: 'Roger'
}
}
}
</script>
In the parent we can access the dog name we passed using:
<page>
<template v-slot="slotProps">
{{ slotProps.dogName }}
</template>
</page>
slotProps is just a variable we used to access the props we passed. You can also avoid setting a variable just to hold the props you pass to the child component, by destructuring the object on the fly:
<page>
<template v-slot="{ dogName }">
{{ dogName }}
</template>
</page> download all my books for free
- javascript handbook
- typescript handbook
- css handbook
- node.js handbook
- astro handbook
- html handbook
- next.js pages router handbook
- alpine.js handbook
- htmx handbook
- react handbook
- sql handbook
- git cheat sheet
- laravel handbook
- express handbook
- swift handbook
- go handbook
- php handbook
- python handbook
- cli handbook
- c handbook
subscribe to my newsletter to get them
Terms: by subscribing to the newsletter you agree the following terms and conditions and privacy policy. The aim of the newsletter is to keep you up to date about new tutorials, new book releases or courses organized by Flavio. If you wish to unsubscribe from the newsletter, you can click the unsubscribe link that's present at the bottom of each email, anytime. I will not communicate/spread/publish or otherwise give away your address. Your email address is the only personal information collected, and it's only collected for the primary purpose of keeping you informed through the newsletter. It's stored in a secure server based in the EU. You can contact Flavio by emailing [email protected]. These terms and conditions are governed by the laws in force in Italy and you unconditionally submit to the jurisdiction of the courts of Italy.