useSlots() VNode tree is not reactive

88 Views Asked by At

I am building a component that manages the layout of its default slot child nodes, for context the general idea is to have something like:

<MyContainer>
   <FooComponent />
   <BarComponent />
   <BazComponent />
</MyContainer>

Where <MyContainer> sets the position and size of foo, bar and baz.

Here is an example of how I would extract the first node (<FooComponent />) from my container:

<script setup lang="ts">
import { computed, useSlots } from 'vue';
    const slots = useSlots()
    const defaultSlot = computed(() => slots.default?.())
</script>   

<template>
    <div style="background-color: red;">
        <component v-if="defaultSlot" :is="defaultSlot[0]"></component>
    </div>
</template>

The issue is that even tho the child component is displayed, it looses its reactivity (see demo), so if any value it depends on changes, it won't reflect that change. I would like to know if there is anything wrong with how I'm accessing the slot, or if there is any other way to properly react to the changes that affect the child components?

Something that would look like a proper workaround at first sight is to have :is use a closure like: :is="() => defaultSlot[0]" as reactivity seems to come back, but I realized that instead this unfortunately causes the whole component to be reloaded every time any reactive property of the parent container changes, so as far as I can tell this approach doesn't work either.

0

There are 0 best solutions below