Slots: programmatic usage improvements #453
Replies: 8 comments 9 replies
-
This would be really helpful. Note, this would be also really useful to have a signature with a string as first parameter, for the slot name, and slot parameters optional second argument getFilledSlot (slot: string, slotProps: any)
getFilledSlot (vnodes: VNodeArrayChildren | null) |
Beta Was this translation helpful? Give feedback.
-
The userland implementation I shared has an issue |
Beta Was this translation helpful? Give feedback.
-
Detecting slots with empty content is one thing, but I think the need goes beyond that. I recently ran into a problem where my template had to adapt according to the number of elements contained in my slot. Filtering the VNodes was quite cumbersome as you explain, especially if you are not familiar with the VNode API, so instead I solved my issue with a watcher and DOM queries. But if felt wrong and definitely non-intuitive. May I suggest |
Beta Was this translation helpful? Give feedback.
-
Other proposal: update |
Beta Was this translation helpful? Give feedback.
-
Worth adding as a reference issue: |
Beta Was this translation helpful? Give feedback.
-
Another idea of API could be one that only requires changes to the template instead of having to rely on <template>
<!-- renders only if slot is not empty -->
<slot-filtered name="foo" v-bind="stuff">
<div class="wrapper">
<!-- automatically inherits everything from the <slot-filtered> parent -->
<slot></slot>
</div>
</slot-filtered>
</template> This would generate a different compiled code than the existing one that also renders the slot just once (maybe a Everything goes on the |
Beta Was this translation helpful? Give feedback.
-
Strange and different idea to solve the problem: An I think most developers intuitively assume that The idea of modifying Scrapping all that, another way that might be the easiest to introduce, would be exporting If I were to solve this in my own codebase today I'd make a composable called |
Beta Was this translation helpful? Give feedback.
-
Is this rfc still in discussion ? Feels like not being able to catch an empty slot is an issue. |
Beta Was this translation helpful? Give feedback.
-
Summary
<script setup>
Basic example
Motivation
It's currently cumbersome and non idiomatic to check if a slot is empty to conditionally render parts of the template. For example, consider this modal component:
We probably don't want to render the
.modal-header
element when the user of the component doesn't put content in theheader
slot.Vue currently only populates the
header
function on$slots
if it is used in the template.But this falls apart as soon as you have some conditionals:
$slots.header
is still populated with the slot render function:So we need to programmatically "render" the slot to check if it's really empty by calling the function:
This also allows us to check for emptiness in case we pass some props to the slot:
We could then check for the length of the vnodes array:
There are two remaining problems here:
HeaderSlot
array of vnodes could contain only "invalid" vnodes such as comments or empty fragments.<slot/>
and we need to duplicate the slot props.Fixing problem 1 requires using an internal function called
ensureValidVNode
to check is the array of vnodes contains other vnodes than comments and empty fragments.That way we can check if the result is
null
, meaning empty:Fixing problem 2 requires directly using in the template the result we have in the script. The most literal way would be to loop over the vnodes:
But it's pretty unreadable and not user-friendly. A probably better alternative is using an intermediate functional component that renders the array of vnodes:
You can find a working example here with all API styles (Options API, Composition API, script setup).
A big developer experience improvement could still be made for problem 2, by directly being able to render an array of vnodes in a template, thus removing the need for an intermediate component:
Note: I like the tag syntax but it implies being able to put attributes on it which wouldn't work. Maybe the compiler can raise warnings about this?
Detailed design
getFilledSlot
is a function that takes an array of vnodes and returns it if it's not empty (i.e. contains valid vnodes),null
otherwise to facilitate conditionals.It could be implemented like this:
Usage:
Note: the returned result from the slot function can be
null
hence the additional conditional ingetFilledSlot
.Allow putting a variable containing an array of vnodes to be used as template tag:
Usage in Option API could be improved if we could resolve template tag using the computed properties:
Drawbacks
getFilledSlot
: This could be implemented in user space but with hacky solutions involving copying an internal function.Adoption strategy
This is an additive API.
Unresolved questions
getFilledSlot
?Beta Was this translation helpful? Give feedback.
All reactions