In Vue 3, how can a block of code in a parent component template be conditionally rendered depending on whether or not a slotted child component has a prop passed to it?
Take the following code for example:
<Foo>
<Bar/>
<Bar baz="baz" />
</Foo>
Conditional slots can be used with $slots
in templates, i.e. v-if="$slots.default"
, but there doesn’t seem to be a way to conditionally render certain content in the parent based on whether or not a slot has a prop.
Inside of <Foo/>
, note the v-if
does not work but this is the idea.
<script setup></script>
<template>
<h1>Foo</h1>
<template v-if="$slots.default.props.baz">
<!-- add custom logic here depending on whether or not "baz" prop is present -->
</template>
<slot/>
</template>
This also will not work:
<script setup></script>
<template>
<h1>Foo</h1>
<template v-for="slot in $slots.default">
<div v-if="slot.props.baz"><!-- do something --></div>
</template>
<slot/>
</template>
The only working solution is to use the useSlots()
composable and use a render function.
<script setup>
const slots = useSlots()
slots.default().forEach(slot => {
if (slots.props?.baz)
console.log('baz prop present')
else
console.log('baz prop not present')
})
</script>
The thing is that vue templates are compiled to render functions, so it would seem that there is a way to access props on $slots
.