2.5.16
https://jsfiddle.net/25bkaes1/
Note that the scoped slot has v-if="false" on it - it seems to me that it should never appear in this.$scopedSlots. Press the "run" button to trigger the initial render.
The console should print "slot missing" and "default slot content" should appear in the rendered div.
The console prints "slot present" and nothing appears in the rendered div. It seems like the v-if is being moved from the slot itself to the slot contents (which is why executing the slot returns nothing rather than "custom slot contents").
Consumers of my component may want to customize how a particular piece is being rendered. Using v-if to toggle this always results in the slot being defined in this.$scopedSlots. Based on this commit it would seem that putting a v-if on a scoped slot is valid usage.
I could in theory check this.$scopedSlots.content() to see if they provided the slot, but this doesn't allow me to determine whether the user provided no slot, or they intentionally provided an empty slot.
As you saw, the scoped slot is still passed but invoking it (since it's a function) will give you undefined (because of v-if=false).
If the user doesn't provide a slot, you will actually get undefined in $scopedSlots, so you can still call the function to check if the user provided a scoped slot with no content
I think it's not logical to set a value anyway in $scopedSlot if the slot is v-if'd away.
I have a twisted case (but still !) where it doesn't work:
http://jsfiddle.net/Owumaro/6umwc3Lx/
I have a first component which accepts a scoped slot. This component passes it down to a subcomponent with a v-if to check if the user provided one.
With the current logic, the subcomponent will either receive the user scoped slot, either an undefined scope (but still set a value in the subcomponent $scopedSlots).
Now the subcomponent wants to pass down the optional scoped slot to a subsubcomponent. Same mechanic: the subcomponent does a v-if to check if the scoped slot exists in its $scopedSlots. But it is always true. So the fallback won't happen if the user gave no scoped slot in the beginning.
This wouldn't happen if the $scopedSlots was empty instead of providing an undefined function.
Let me know if this makes sense or if my way of passing down scoped slots is wrong.
Thanks
I just ran into this today, I find it strange that regular slots and scoped slots behave differently with v-if on them: https://codesandbox.io/s/jl6xkv34y5
I would expect that scopedSlots work like the OP proposed which is the same as how regular slots work
I agree, this is really unintuitive. I had a regular slot first, then needed to pass some context so I made it a scoped slot – and suddenly, the tests if slot content was passed just didn't work anymore (even without me noticing in the beginning).
This would obviously be a breaking change, so it cannot easily be fixed — but I'd be interested in the reasoning behind the inconsistent APIs for both slot types?
This is still an issue and should be looked into. I'm also seeing inconsistent behavior in regular vs scoped slots. You cannot check if this.$scopedSlots is set because it'll return "cannot call function of undefined".
scoped slot and regular slot behave differently because scoped slots need to wait for the child component to invoke the function to pass the data whereas regular slots do not need any information and are invoked in the parent, before being passed down to the child consuming the slot. That's also why regular slots directly contain the vnode instead of a function.
This difference disappears with v-slot (they are like scoped slots) and will also be united into one single concept in the future
scoped slot and regular slot behave differently because scoped slots need to wait for the child component to invoke the function to pass the data whereas regular slots do not need any information and are invoked in the parent, before being passed down to the child consuming the slot. That's also why regular slots directly contain the vnode instead of a function.
This difference disappears with v-slot (they are like scoped slots) and will also be united into one single concept in the future
So how would we check if a slot in a child has been defined, so we know if we should display it or not?
Eg. a table with content appended to a row. That'll need a td, but only if the slot has content in the slot. If not we should not display that td. How would we check for the status, if we have to wait for the child to finish invoking?
Most helpful comment
So how would we check if a slot in a child has been defined, so we know if we should display it or not?
Eg. a table with content appended to a row. That'll need a td, but only if the slot has content in the slot. If not we should not display that td. How would we check for the status, if we have to wait for the child to finish invoking?