Description
There are some times in component composition when we need the ability to determine whether a slot has been passed down by the user of the component with some content. In Vue 2 we could check this easily:
<div v-if="this.$slots.mySlot">
<p>Some unrelated content to the slot or extra markup</p>
<slot name="mySlot" />
</div>
With the addition of fragments and the changes to the slot system in Vue 3, this simple truthy/falsy check is no longer possible since a slot function will return a truthy object when containing empty text, comments, fragments, etc.
Vue internals are checking this here: https://github.com/vuejs/vue-next/blob/8610e1c9e23a4316f76fb35eebbab4ad48566fbf/packages/runtime-core/src/helpers/renderSlot.ts#L59
However, there is no official way to do this on the user end that I have found that works 100% of the time without having to tap into undocumented internal API.
Some folks are suggesting checking against the symbol in vnode.type
, which works in theory however it seems that when compiled these symbols usually evaluate to undefined. It also creates a very hard-to-maintain series of if
checks to try to determine the type of vnode that is being received, along with a combination of checks on its `children.
There was an attempt to request this early in January, but sadly it was closed and dismissed with some answers that don't seem to fully solve the problem. vuejs/core#3056
The dream would be to expose some sort of slotIsEmpty
(naming?) function through the vue
package, similarly to how we are getting isRef
, etc. that would simplify solving this particular problem.