Say we have a component template that provides multiple named slots together with an unnamed one. The default slot is enclosed by named slots, like in the example.
<slot name="first"> <span>first slot</span> <slot> <p>this is the default slot</p> </slot> <slot name="second"> <span>second named slot</span> </slot>
The problem arises when you overwrite the named slots, but not the default one. In that case, every piece of whitespace gets loaded as the default slot, which makes it disappear from the DOM.
https://jsfiddle.net/u74hztk7/
slot API replaces the inner content of the declared slot with the content distributed. You can controll the white space by distributing structure to the slot... <div slot="first"><p>First slot<p></div> with structured distributed content. See example above to see full example.
I don't believe you understand the actual issue I'm explaining here. The problem is not how slot API works, I actually find it a great feature of Vue templates.
The actual problem is the default slot becomes empty when any form of whitespace is present between 2 named slots. Removing this whitespace (by making their dom elements follow each other seamlessly) is the only way to actually have the default slot show up with the content provided in its original template.
Again, a simplified example:
Works because both slots follow each other without whitespace
<div slot="first">first slot</div><div slot="second">second slot</div>
Doesn't work, because whitespace is present (a newline)
<div slot="first">first slot</div>
<div slot="second">second slot</div>
Same JSFiddle example as above which has the template's definition
PS: I'm not sure what you're trying to show with your fiddle link. It's an exact copy of the one I provided.
@MichelPaus Thank you for the clarification. Mis-communication, i thought you were suggesting that the output was not formatted in the manner of <p>Some text</p>.
What i think you are trying to say is.
If white space is present with no real defined distributable content to a default slot, it outputs the default slot with no content.
@yyx990803
The initial description and fiddle were a bit confusing to me. I don't know if this fiddle better demonstrates the issue.
There are two axes:
When the named slots are not used, whitespace has no effect. When the named slots are used, whitespace overwrites the default slot. This is inconsistent with the first case, where whitespace has no effect.
Hi @MichelPaus,
Did you find a solution? I guess, I have a similar problem:
I created a custom Vue select/dropdown component which I want to use in normal HTML templates. In the default slot, I pass the options, like so:
<my-select placeholder="Please select a title">
<option value="0">-</option>
<option value="1">Dr.</option>
<option value="2">Prof.</option>
<option value="3">Dr.-Ing.</option>
<option value="4">Dr.-med.</option>
</my-select>
Within the Vue component, I then process the slot content. When inspecting in Chrome, I see that every whitespace between the options is treated as an own DOM element (n in this case is slots.default()):

For now I solved it by manually filtering for undefined tags in the slots:
const options: VNode[] = [];
function setOptions(): void {
slots.default().forEach((option) => {
if (option.tag !== undefined) {
options.push(option);
}
});
}
But since I think this is pretty dirty, I'd be very interested in a better solution.
Cheers, Nanda
@NandaYogeshwar
Any luck on a more elegant solution? I also came to your solution but felt that it was a bit too gross so came looking for a better way. It looks as if it's either checking if the slot is undefined or placing everything in one line which kills the readability of the code.
Most helpful comment
The initial description and fiddle were a bit confusing to me. I don't know if this fiddle better demonstrates the issue.
There are two axes:
When the named slots are not used, whitespace has no effect. When the named slots are used, whitespace overwrites the default slot. This is inconsistent with the first case, where whitespace has no effect.