Defer evaluation of conditionally rendered slots?

I have a Loader component which accepts the contents that should be rendered when its loading property is false in it’s default slot. When the loading property is true it renders a default loading animation, which can also optionally be overridden by a named slot. I am using this when fetching data from an API, and was hoping to circumvent the need for a … by using the following setup in the Loader component:

<template>
  <div>
    <slot name="loader" v-if="isLoading">
      <ContentLoader />
    </slot>
    <slot v-else></slot>
  </div>
</template>

However, the default slot contents seem to be already evaluated in the parent component even if isLoading is true, whilst in that case the slot isn’t even defined in the Loader component. This causes errors because the default slot contents I want to render depend on the data being fetched an available. So instead of being able to do this in the parent:

<template>
  <Loader :loading="isLoading">
    ....
  </Loader>
</template>

I now still have to do this:

<template>
  <Loader :loading="isLoading">
    <template v-if="!isLoading">
      ...
    </template>
  </Loader>
</template>

Is there any way to circumvent the need for the extra, redundant ?

you can use a scoped slot.

<template slot-scope="_">
  ...
</template>

Could you explain how this solves my issue? A scoped slot does not seem the obvious choice because I don’t have to access child component state in the parent component? And how exactly do they differ in when they are evaluated from “normal” slots?

Well, scoped slots are essentially un-evaluated templates that are handed to the child component, which can then render this template where and how often it wants, with whatever props it wants to pass it.

The “normal” usecase is to actually access child state through the slot-scope props, but you don’t have to make use of that. The part that’s important for you is that scoped slot templates are not rendered in the parent, the are only evaluated and rendered when the child decides to do so.

So you can essentially use a scoped slot as a deferred slot.

I find it remarkable that a v-if does not delay evaluation when the condition evaluates to false. This is inconsistent with behavior of conditional logic in most other programming environments.

The current documentation states that slot-scope is deprecated. Can anyone comment as to how to achieve this deferred behavior in 2.6?

Pardon me but I’m not sure which part of this conversation you are referring to with this remark - in my defense this topic is 1 year old. can you clarify?

The current documentation states that slot-scope is deprecated. Can anyone comment as to how to achieve this deferred behavior in 2.6?

The new v-slot directive (as documented) does the same thing technically, just with a new syntax. Plus, it’s always “deferred”. so just use v-slot