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?

Don't miss out anything about Vue, your favourite framework.

Subscribe to receive all the articles we publish in a concise format, perfect for busy devs.

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.

Anthony Konstantinidis

Anthony Konstantinidis

Jul 18, 2022

Data Provider component in Vue.js

Use scoped slots to create a data provider in Vue.js

Alex Jover Morales

Alex Jover Morales

Sep 24, 2019

Using Scoped Slots in Vue.js

Quick example on how to use scoped slots for component reusability in vuejs

Alex Jover Morales

Alex Jover Morales

Sep 15, 2019

Sponsors

VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.

Silver
Learning Partner