Subscribe on changes!

[Bug] When `slot` is used with `v-if`, the slot content is not displayed as expected

avatar
Dec 1st 2022

Vue version

^3.2.45

Link to minimal reproduction

https://sfc.vuejs.org/#eNqFks9ugzAMxl/Fy6WdVMgd0W5TpZ33AFwoGJo2JFES6AHx7nOAUfb/BHbsn/N9Ts9ejIm7FlnCUldYYTw49K05ZEo0RlsPPVisYIDK6gY2VLpZjo5a+VwotPNhzJdMYFJhpgqtHDHP+gb7QNpWuXT4mKmUT/NoEgUeGyNzjxQBpKfWe63guZCiuO4zNrc/hG/GxhoAr+taIkTQ9xN/GMZmPnVPpPsVk1ATFWchS4uKoGta5tNSdNBFoprHLWMA3qzuRInlqBeVn/Ipp45pyF02xSlftLAdm5yKmtzEF6cV2dyP8+YDl7EExkzIkWchztjZe+MSzl1VBCMvLta25vQX21Z50WCMrolOVt8cWX0hym7F4JTs0EYks0SL9i/ml9Jv3IAlWweS8mm3q/cic1WTaUHL8nagxIpKyTnj0klfMPU4u/+UwElriTmtHobD9p/n4KQO+Z/W9EFcres1l/KUF9ff1zXz1psa3gFE5As4

Steps to reproduce

  1. open the reproduction link
  2. click the toggle button
  3. observe whether the slot content is toggled.

What is expected?

  1. The provided content should be displayed when show is true.
  2. The fallback content should be displayed when show is false.

What is actually happening?

The slot content is not toggled.

System Info

No response

Any additional comments?

No response

avatar
Dec 1st 2022

a workaround

<Container :show-children="!show">
    <div v-if="show" :key="1">   // add a key
    Provided Content
  </div>
</Container>
avatar
Dec 1st 2022

a workaround

<Container :show-children="!show">
    <div v-if="show" :key="1">   // add a key
    Provided Content
  </div>
</Container>

This method can temporarily solve this problem, but if the component comes from an external library, we may need to find ways to avoid key repetition.

avatar
Dec 1st 2022

this is because of the slot children and the fallback children both as blocks but with empty dynamic children.

@nooooooom

<template>
  <slot>
      <div> // remove v-if also works.
      Fallback Content
    </div>
  </slot>
</template>

I usually use $slots.default to determine if need to display the fallback content

<slot v-if="$slots.default">
  <div>
    Fallback Content
  </div>
</slot>
avatar
Dec 5th 2022

this is because of the slot children and the fallback children both as blocks but with empty dynamic children.

@nooooooom

<template>
  <slot>
      <div> // remove v-if also works.
      Fallback Content
    </div>
  </slot>
</template>

I usually use $slots.default to determine if need to display the fallback content

<slot v-if="$slots.default">
  <div>
    Fallback Content
  </div>
</slot>

Thank you for your suggestion. Currently, I was able to solve my problem this way.

But this may still be something Vue needs to address, as it doesn't align with the usage as stated in the documentation.