Vue <slot> Element
Example
Using the built-in <slot>
element to place content from the parent component in the <template>
of the child component.
<template>
<div>
<p>SlotComp.vue</p>
<slot></slot>
</div>
</template>
Run Example »
See more examples below.
Definition and Usage
The built-in <slot>
element is used to place content received from the parent component.
When a child component is called, content provided between the start- and end-tag will end up where the <slot>
element is inside that child component.
A component can hold more than one <slot>
, and the slots can be named with the name
prop. With such components with different named slots, we can use the v-slot
directive to send content to specific slots. (Example 3)
Content between the start- and end-tag of the <slot>
element will be used as fallback content if no content is provided by the parent. (Example 5)
Information can be provided up to the parent element through <slot>
props. (Example 8)
The <slot>
element is just a placeholder for content, the <slot>
element itself is not rendered into a DOM element.
Props
Prop | Description | |
---|---|---|
[any] | Props defined in slots create 'scoped slots' and such props are sent to the parent. | Run Example » |
name | Names a slot so that the parent can direct content into a specific slot with the v-slot directive. |
Run Example » |
More examples
Example 1
Using slots to wrap around larger chunks of dynamic HTML content to get a card-like appearance.
App.vue
:
<template>
<h3>Slots in Vue</h3>
<p>We create card-like div boxes from the foods array.</p>
<div id="wrapper">
<slot-comp v-for="x in foods">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
<p>{{x.desc}}</p>
</slot-comp>
</div>
</template>
As the content enters the component where the <slot>
is, we use a div around the <slot>
and style the <div>
locally to create a card-like appearance around the content without affecting other divs in our application.
SlotComp.vue
:
<template>
<div> <!-- This div makes the card-like appearance -->
<slot></slot>
</div>
</template>
<script></script>
<style scoped>
div {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
border-radius: 10px;
margin: 10px;
}
</style>
Run Example »
Example 2
Using a slot to create a footer.
App.vue
:
<template>
<h3>Reusable Slot Cards</h3>
<p>We create card-like div boxes from the foods array.</p>
<p>We also create a card-like footer by reusing the same component.</p>
<div id="wrapper">
<slot-comp v-for="x in foods">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
</slot-comp>
</div>
<footer>
<slot-comp>
<h4>Footer</h4>
</slot-comp>
</footer>
</template>
Run Example »
Example 3
Using slot names, content can be sent to a specific slot.
SlotComp.vue
:
<h3>Component</h3>
<div>
<slot name="topSlot"></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp v-slot:bottomSlot>'Hello!'</slot-comp>
Run Example »
Example 4
With two slots in a component, content sent to the component will end up in both slots.
App.vue
:
<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp>'Hello!'</slot-comp>
SlotComp.vue
:
<h3>Component</h3>
<div>
<slot></slot>
</div>
<div>
<slot></slot>
</div>
Run Example »
Example 5
Using fallback content in a slot so that something is rendered when no content is provided from the parent.
App.vue
:
<template>
<h3>Slots Fallback Content</h3>
<p>A component without content provided can have fallback content in the slot tag.</p>
<slot-comp>
<!-- Empty -->
</slot-comp>
<slot-comp>
<h4>This content is provided from App.vue</h4>
</slot-comp>
</template>
SlotComp.vue
:
<template>
<div>
<slot>
<h4>This is fallback content</h4>
</slot>
</div>
</template>
Run Example »
Example 6
The slot without a name will be the default slot for content from the parent.
SlotComp.vue
:
<h3>Component</h3>
<div>
<slot></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp>'Hello!'</slot-comp>
Run Example »
Example 7
Using v-slot:default
to explicitly define a slot as the default slot.
SlotComp.vue
:
<h3>Component</h3>
<div>
<slot></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp v-slot:default>'Default slot'</slot-comp>
Run Example »
Example 8
Scoped slot: Using the 'foodName' prop in the slot to communicate the food name to the parent.
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x"
:foodName="x"
></slot>
</template>
<script>
export default {
data() {
return {
foods: ['Apple','Pizza','Rice','Fish','Cake']
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<h2>{{ food.foodName }}</h2>
</slot-comp>
Run Example »
Example 9
Scoped slot: Using props in the slot to communicate the several things to the parent, based on an array with objects.
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x.name"
:foodName="x.name"
:foodDesc="x.desc"
:foodUrl="x.url"
></slot>
</template>
<script>
export default {
data() {
return {
foods: [
{ name: 'Apple', desc: 'Apples are a type of fruit that grow on trees.', url: 'img_apple.svg' },
{ name: 'Pizza', desc: 'Pizza has a bread base with tomato sauce, cheese, and toppings on top.', url: 'img_pizza.svg' },
{ name: 'Rice', desc: 'Rice is a type of grain that people like to eat.', url: 'img_rice.svg' },
{ name: 'Fish', desc: 'Fish is an animal that lives in water.', url: 'img_fish.svg' },
{ name: 'Cake', desc: 'Cake is something sweet that tastes good but is not considered healthy.', url: 'img_cake.svg' }
]
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<hr>
<h2>{{ food.foodName }}<img :src=food.foodUrl></h2>
<p>{{ food.foodDesc }}</p>
</slot-comp>
Run Example »
Example 10
Using named scoped slots to put one text into the "leftSlot", and another text into the "rightSlot".
SlotComp.vue
:
<template>
<slot
name="leftSlot"
:text="leftText"
></slot>
<slot
name="rightSlot"
:text="rightText"
></slot>
</template>
<script>
export default {
data() {
return {
leftText: 'This text belongs to the LEFT slot.',
rightText: 'This text belongs to the RIGHT slot.'
}
}
}
</script>
App.vue
:
<slot-comp #leftSlot="leftProps">
<div>{{ leftProps.text }}</div>
</slot-comp>
<slot-comp #rightSlot="rightProps">
<div>{{ rightProps.text }}</div>
</slot-comp>
Run Example »
Related Pages
Vue Tutorial: Vue Slots
Vue Tutorial: Vue v-slot
Vue Tutorial: Scoped Slots
Vue Tutorial: Components
Vue Reference: Vue v-slot directive
Vue Reference: Vue $slots Object