Vue 2.6 is released with new syntax for Slots using v-slot
directive. In this tutorial, we’re gonna show you:
- Syntax to use Vue Slot with
v-slot
directive along with its shorthand - How to use Vue Named Slots with
v-slot
& examples - How to use Vue
v-slot
for Scoped Slots & examples - Vue Dynamic slots example
Related Post: Vue 3 Composition API tutorial with examples
Contents
Vue slots syntax with v-slot directive
With new v-slot
directive, we can:
– combine html layers: component tag and scope of the slot.
– combine the slot and the scoped slot in a single directive.
For example, this is old syntax with slot-scope
:
{{item}}
This is how we combine ListComponent
and template
tag:
{{item}}
And this is old named slots syntax:
<base-component>
<p slot="header">Header</p>
<template slot="content" slot-scope="{data}">
<h2>{{data.title}}</h2>
<p>{{data.text}}</p>
</template>
<p slot="footer">Footer</p>
</base-component>
Now we use new Vue v-slot
directive:
<base-component>
<template v-slot:header>
<p>Header</p>
</template>
<template v-slot:content="{data}">
<h2>{{data.title}}</h2>
<p>{{data.text}}</p>
</template>
<template v-slot:footer>
<p>Footer</p>
</template>
</base-component>
You can see that:
– We use <template v-slot:header>
to wrap <p>
tag instead of <p slot="header">
directly. This is because Vue v-slot
can only be used in <component>
or <template>
html tag. It cannot be used in plain HTML tags (<p>
for example).
– We replace slot="content" slot-scope="{data}"
with v-slot:content="{data}"
by combining slot
& slot-scope
. With new Vue v-slot
directive, all slots are compiled into scoped slots. It improves the performance. Why?
Normal slots are rendered during the parent component’s render cycle. So, if any dependency of a slot changes, both the parent and child components will be re-rendered.
When we use scoped slots, slots are compiled into inline functions and called during the child component’s render cycle. This means:
- data from a scoped slot are collected by the child component which is re-rendered separately.
- the changes of parent scope dependency only affect the parent, not the child component. So the child component doesn’t need to update if it uses only scoped slots.
Shorthand for v-slot
#
is the shorthand for Vue v-slot
directive.
For example, #content
stands for v-slot:content
.
The code above can be written as:
<base-component>
<template #header>
<p>Header</p>
</template>
<template #content="{data}">
<h2>{{data.title}}</h2>
<p>{{data.text}}</p>
</template>
<template #footer>
<p>Footer</p>
</template>
</base-component>
Remember that when using shorthand, we must always specify the name of the slot after #
symbol. We cannot use shorthand like this: #="{item}"
.
It must be: #default="{item}"
in which, #default
is the shorthand for v-slot:default
.
In the next parts, we show you some examples that apply new Vue v-slot
directive in practice.
Vue v-slot examples with Named Slots
If we want to use multiple slots in one component, Named Slots are useful.
The code below shows BkrCard
component template with 3 slots:
- header
- title
- default
<template>
<div class="card">
<div class="card-img-top">
<slot name="header"></slot>
</div>
<div class="card-body">
<div class="card-title">
<slot name="title">Default Card title</slot>
</div>
<div class="card-text">
<slot>This is just a default Card text</slot>
</div>
</div>
</div>
</template>
Remember that <slot>
without name
attribute has the name default
.
Now look at the parent component which use v-slot
directive to specify name for named slots on <template>
tag:
<bkr-card>
<template v-slot:header>
<img src="https://bezkoder.com/wp-content/uploads/2019/06/bezkoder-test-feature-image.png">
</template>
<template v-slot:title>
<p>BezKoder for mobile developers</p>
</template>
<template v-slot:default>
<p>BezKoder.com is built for specific goal: programming languages & technique for mobile application, cross-platform software development.</p>
<bkr-button>Read more</bkr-button>
</template>
</bkr-card>
The result will be:
If we pass only one named slot, the default value will be shown:
<bkr-card>
<template v-slot:header>
<img src="https://bezkoder.com/wp-content/uploads/2019/06/bezkoder-test-feature-image.png">
</template>
</bkr-card>
Vue v-slot example with default slot
In the example above, we use <template v-slot:default>
for the default slot.
We have other ways to specify html code to be considered as default slot also:
– wrap it in a <template>
without Vue v-slot
directive:
<bkr-card>
<template v-slot:header>
<img src="https://bezkoder.com/wp-content/uploads/2019/06/bezkoder-test-feature-image.png">
</template>
<template v-slot:title>
<p>BezKoder for mobile developers</p>
</template>
<template>
<p>BezKoder.com is built for specific goal: programming languages & technique for mobile application, cross-platform software development.</p>
<bkr-button>Read more</bkr-button>
</template>
</bkr-card>
– do not wrap it in a <template>
:
<bkr-card>
<template v-slot:title>
<p>BezKoder for developers</p>
</template>
<p>BezKoder.com is built for specific goal: programming languages & technique for mobile application, cross-platform software development.</p>
<bkr-button>Read more</bkr-button>
<template v-slot:header>
<img src="https://bezkoder.com/wp-content/uploads/2019/06/bezkoder-test-feature-image.png">
</template>
</bkr-card>
The result are the same for 2 cases:
Vue v-slot examples with Scoped Slots
What we should do when we want a child component to allow parent component access its data?
In this example, categories
need to be available to the slot content in the parent. So we bind the categories
as an attribute to the <slot>
element:
<template>
<span>
<slot :categories="categories"></slot>
</span>
</template>
<script>
export default {
data() {
return {
categories: ["Dart", "Flutter", "Vue.js"],
};
}
};
</script>
The categories
attribute is called slot props.
In the parent scope, Vue v-slot
directive can help us get value of the slot props above:
-
{{ category }}
The result will be:
- Dart
- Flutter
- Vue.js
This is shorthand for v-slot
:
-
{{ category }}
Vue Dynamic slots example
We can use a JavaScript expression in v-slot
directive argument with square brackets:
{{data.item}}
Now look at the example:
<bkr-categories v-slot:[collection]="{categories}">
<ul>
<li v-for="category in categories" :key="category">
{{ category }}
</li>
</ul>
</bkr-categories>
<button class="btn btn-outline-secondary" @click="changeCollection">Change</button>
<script>
import BkrCategories from "./components/BkrCategories.vue";
export default {
components: {
BkrCategories
},
data() {
return {
collection: "default"
};
},
methods: {
changeCollection() {
if (this.collection === "default") this.collection = "new_categories";
else this.collection = "default";
}
}
};
</script>
Clicking on the Change button will change the collection
value dynamically.
v-slot:[collection]="{categories}"
could become:
v-slot:default="{categories}"
v-slot:new_categories="{categories}"
This is BkrCategories
component with default
and new_categories
slot name:
<template>
<span>
<slot :categories="categories"></slot>
<slot name="new_categories" :categories="newCategories"></slot>
</span>
</template>
<script>
export default {
data() {
return {
categories: ["Dart", "Flutter", "Vue.js"],
newCategories: ["Mobile", "Cross Platform", "Frontend Tech"],
};
}
};
</script>
The result will be:
Conclusion
We’ve learned almost aspects of new Vue v-slot
directive, from v-slot
syntax to its handshort, then apply v-slot
directive on Named Slot examples to Scoped Slots and Dynamic Slots examples.
Happy learning! See you again!
Very good tutorial. I absolutely love this site. Continue the good work!
Your tutorial is awesome!!
Hi, thanks for your articles, it really helped me
This Vue tutorial is in fact a good one it helps new developers.
Hi there, I read your new tutorial every week. Keep doing what you’re doing!
Thanks!
I used to be suggested this website and Vue tutorials through my friends.
You are wonderful! Thank you!
Thank you a lot for this Vue tutorial!
Great Vue tutorial.
Thank you and best of luck.
Many Thanks!
Thanks for your tutorial!
Wow, your Vue tutorial is what I was looking for. Thanks admin of this website.
Many many Thanks! Love all your Vue tutorials.
Many Thanks for this comprehensive Vue tutorial!
Thanks a Million! for this Vue tutorial!
Wonderful post! We are linking to this great content on our
website. Keep up the good writing.
This Vue tutorial is very helpful. Thanks!
Very useful Vue tutorial with comprehensive cases about v-slot. Thank you.
Thank you for introducing the Vue v-slot with many cases to practice. 🙂
I’m looking forward to seeing many Vue tutorials from you.
I would like to say thank you so much for this Vue tutorial.
Thank you so much for your effort to make this Vue tutorial!
Thank you for this v-slot tutorial, it helps me alot.
Comprehensive v-slot tutorial, great job!
Hey I know this is off topic but I was wondering if you knew of any widgets I could
add to my blog that automatically tweet my newest twitter
updates. I’ve been looking for a plug-in like this for quite
some time and was hoping maybe you would have some experience with something like this.
Please let me know if you run into anything. I truly
enjoy reading your blog and I look forward to your new updates.
Thanks for great tutorial about Vue v-slot, this is what I was looking for.
This is the right tutorial for anyone who want to learn about Vue v-slot. Thanks!
Thanks so much! This Vue tutorial is exactly what I am looking for. Waiting for more Vue 3 tutorials from you.
Thank you bezkoder for writing this v-slot tutorial. It covers many aspects to work with Vue slots.
Excellent work! Thanks for the comprehensive v-slot tutorial.
Thanks for this comprehensive tutorial. Now I can understand new Vue v-slot feature deeply.
Hi, thank you so much for your effort to make this Vue tutorial. Vue v-slot is new to me, and this tutorial helps me alot.
I like what you guys are up too. Such clever work and reporting! Thank you for the tutorial.