How to use the new v-slot directive in Vue.js
I'm so excited to see how's people liking VueDose! I received amazing feedback about the performance tips published so far. I'm so grateful about the support and the compliments 🤗.
Last week the version 2.6.0-beta.3 of Vue.js was released, enabling a new feature to simplify scoped slots even more.
It introduces the new v-slot
directive and its shorthand, as described in the RFC-0001 and RFC-0002.
In order to understand how it does simplify the syntax, let's see how's it in current scoped slots. Imagine you have a List
the component that exposes a filtered list as its scope.
The way you'd use that List scoped slot would be similar to:
<template>
<List :items="items">
<template slot-scope="{ filteredItems }">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</template>
</List>
</template>
The implementation of the List component is not too relevant, but in this Codesandbox you can check an example of it.
With v-slot
, you can write the scope of that slot directly on the component tag, avoiding an extra layer:
<template>
<List v-slot="{ filteredItems }" :items="items">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</List>
</template>
Keep in mind v-slot
can only be used on components and template
tags, but not in plain HTML tags
This makes the code more readable specially when you have nested scoped slots, which can be difficult to reason where a scope comes from.
The v-slot
directive also introduces a way to combine the slot
and the scoped-slots
directive, but by separating them with a colon :
.
For example, this example taken from vue-promised:
<template>
<Promised :promise="usersPromise">
<p slot="pending">Loading...</p>
<ul slot-scope="users">
<li v-for="user in users">{{ user.name }}</li>
</ul>
<p slot="rejected" slot-scope="error">Error: {{ error.message }}</p>
</Promised>
</template>
Could be written with v-slot
as follows:
<template>
<Promised :promise="usersPromise">
<template v-slot:pending>
<p>Loading...</p>
</template>
<template v-slot="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template v-slot:rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
And to end up, v-slot
has the symbol #
as a shorthand, so the example before could be written as:
<template>
<Promised :promise="usersPromise">
<template #pending>
<p>Loading...</p>
</template>
<template #default="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template #rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
Just keep in mind that the shorthand for the default v-slot
is #default
.
Are you excited about this new slot syntax?
Related Articles
The new Provide and Inject in Vue 3
Getting stuck into the prop drilling? Learn how provide/inject can make your components more flexible and independent in this short tutorial.
Jul 18, 2022
Sep 24, 2019
Using Scoped Slots in Vue.js
Quick example on how to use scoped slots for component reusability in vuejs
Sep 15, 2019
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.