giraud florent

Vue 2.6.6 Release part2 new v-slot syntax

v-slot and scoped slot new syntax

As I am saying in my last article we will take a simple example and try to reproduce the behavior of the awesome vue-promise component HERE made by Posva.

What do we want to achieve here ?

1) create a component Promise 2) it should display loading when pending 3) It should display error when error. Here we will need a scoped slot for displaying the error.message 4) Show data when it's loaded without error

đŸ’ª đŸ¤˜Don't run away !!! :smile:

At any moment you can see the final codes:

Old slot and slot-scope

// App.vue
<template>
  <div>
    <PromiseComponent :promise="childrenPromise">
      <span slot="pending">Loading... !</span>

      <template slot-scope="{ data }">
        <ul>
          <element v-for="name in data" :key="name"> {{ name }} </element>
        </ul>
      </template>

      <p slot="rejected" slot-scope="{ error }">{{ error.message }}</p>
    </PromiseComponent>
  </div>
</template>

New Slot Scoped slot Syntax

// App.vue
<template>
  <div>
    <PromiseComponent :promise="childrenPromise">
      <template #pending>
        <span >Loading... !</span>
      </template>

      <template #default="{data}">
        <ul>
          <Element v-for="name in data" :key="name">
            {{ name }}
          </Element>
        </ul>
      </template>

      <template #rejected="{error}">
        <p>Error... :( : {{ error.message }}</p>
      </template>
    </PromiseComponent>
  </div>
</template>

they both have same subFiles:

// /components/Promise.vue
<template>
  <div>
    <slot v-if="isLoading" name="pending" :isLoading="isLoading"></slot>
    <slot v-if="!isLoading" name="default" :data="data"></slot>
    <slot v-if="error" name="rejected" :error="error"></slot>
  </div>
</template>

PS: I have put here the most important files. If you want to check more go to :

Yeah it's a lot of codes ! But it's ok trust me :smile:

For the old syntax i showed you how differently you can write them. It is a basic example without a lot of nested components... And for me it seems to be messy..

Sometimes with this syntax scoped slots can be really weird because you can't know where slotProps come from. What I dislike too is that you have to write two directives slot and slot-scope.

It worked well before but it can be better ! :smile:

In the new syntax they finally decided to regroup them into one directive. v-slot.

IMPORTANT 1: You need to know v-slot can only be used in <component /> or <template/> html tag. It canno't be use in <p> by example

I like the idea of regrouping all in one v-slot:default

(#default is the shorthand for v-slot:default)

#:[slotNAme]=[slotPros]

Last thing i like a lot is the performance improvement !

For now according to EvanYou

Normal slots are rendered during the parent’s render cycle. When a dependency of a slot changes, it causes both the parent and child components to re-render

What it mean ?

CHECK HERE

As you can see when you open the console. Even if you update a data in parent or in a children slot it update the normal scope. This is the performance issue point by Evan you.

But wait ... The slot scope didn't update !?

Yes. According to Evan you

Scoped slots, on the other hand, are compiled into inline functions and called during the child component’s render cycle. This means any data dependencies relied on by a scoped slot are collected by the child component, resulting in more precise updates

So here it will update when his children will update and not with his parents !

All slots using the new v-slot syntax are compiled into scoped slots. So with the new syntax you just don't have to think about the performance issue. It is done by default :clap: :clap: :clap: