'Vue3 Manually Render Slot Content

I'm trying to parse out the contents of a slot and render the contents in multiple places. The idea is to create a wizard that allows each step to be contained in a single component. Something like this:

Wizard Component Definition:

<ul>
    <li v-for="icon in icons">{{icon}}<li>
</ul>
<section>
    <ul>
        <li v-for="body in bodies">{{body}}</li>
    </ul>
</section>

Wizard Component Script

import {ref} from "vue";

export default {
    setup(props, {slots}) {
        const icons = ref([]);
        const bodies = ref([]);

        for (let item of slots.default()) {
            // not sure if I need to call these, ex: item.children.icon()
            icons.value.push(item.children.icon);
            bodies.value.push(item.children.body);
        }
        
        return {icons, bodies};
    }
}

Wizard Component Usage:

<wizard>
    <wizard-page>
        <template #icon>someIcon</template>
        <template #body>someBody</template>
    </wizard-page>
    <wizard-page>
        <template #icon>someIcon2</template>
        <template #body>someBody2</template>
    </wizard-page>
</wizard>

The obvious problem here is that everything is VNodes and doesn't just render nicely to the DOM. I've tried using render() and h() but those don't seem to be what I'm looking for. Also tried the v-html binding, but again, that isn't expecting a VNode.

I'm not sure if there's a better way to do this, or if I'm missing something simple here, but I'm not seeing an easy way to split apart a slot and render the contents in different places.



Solution 1:[1]

VUE 3

<component :is="body">

You can implement it in the following way

<ul>
  <li v-for="body in bodies" :key="uniquekey">
    <component :is="body" />
  </li>
</ul>

link to docs: https://vuejs.org/guide/essentials/component-basics.html#dynamic-components

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mike