I wanna write custom vue 3 component for collapse. It has button and collapsible content. But button and collapsible content are not always at the same level in template. For example, Button can be part of an input-group. So, here is multi level slot nesting component (with bootstrap):
<script setup>
defineProps({
cssId: String
})
</script>
<template>
<slot name="input-group">
<div data-bs-toggle="collapse" :data-bs-target="cssId" aria-expanded="false" aria-controls="filterCollapse">
<slot name="button">
</slot>
</div>
</slot>
<div class="collapse" :id="cssId">
<slot name="content"></slot>
</div>
</template>
I'v tried it this way:
<Collapse css-id="filterCollapse">
<template #input-group>
<div class="input-group">
<input type="text" class="form-control" placeholder="Поиск...">
<template #button>
<button class="btn btn-outline-secondary d-lg-none d-sm-block" type="button">
<i class="bi bi-filter mb-3"></i>
</button>
</template>
</div>
</template>
<template #content>
...
</template>
</Collapse>
How can I use this component? (got Syntax Error: Error: Codegen node is missing for element/if/for node. Apply appropriate transforms first.) Are there better ways to resolve this issue?
You define your slot button
inside the default content of the input-group
slot.
<slot name="input-group">
<div data-bs-toggle="collapse" :data-bs-target="cssId" aria-expanded="false" aria-controls="filterCollapse">
<slot name="button">
</slot>
</div>
</slot>
This means, that if you fill your input-group
slot with some content, then this content overwrites the default slot content and then there is no slot button
anymore.
<template #input-group>
<div class="input-group">
It does not work this way. Please check that you understand the slot's Fallback Content and rethink your design.
You will possibly need to use Vue Render Functions to achieve your goal.