-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Child component <slot v-if="false"> will still evaluate parent slot code #8578
Comments
Hi! If I understand it correctly, this is not a bug.
This is the compiled render function of your App component. Notice how I'd say this is expected behaviour, because that v-if prevents rendering, not parsing/evaluation (AFAIK). Hope it helps! |
No, that is not correct. Demo: <!-- this will work just fine because it's not evaluated -->
<div v-if="false">
{{ example.should.not.be.called }}
</div> <!-- this will be an error because it is evaluated -->
<div v-show="false">
{{ example.should.not.be.called }}
</div> |
Hi again! 👋 Now I see that in my comment I didn't state clearly that I was talking about the However, I'd say this is an expected behaviour because "everything in the parent template is compiled in parent scope" (source). And in your parent component, Be that as it may, maybe the docs should reflect this edge case somewhere. Or at least a warning? |
I am not sure why you’re commenting on my issue, I’m not asking for help, I’m reporting a bug. |
This is expected behavior as @afontcu has explained. Parent slot content is "rendered" into VNode eagerly before being passed down to child for slot resolution. If you want it to be lazy, use scoped slots. In the future we may make all slot content lazy by default, but not until we have the opportunity to make breaking changes (i.e. 3.0) |
@afontcu We just upgraded to Vue and started experiencing this issue. Do you happen to know if the default slot content was always eagerly loaded? We had a layout template with a v-if statement that showed a loading screen until content was loaded and were surprised to find it breaking due to this after an upgrade to 2.6.10. |
You can use the new |
I'd just like to elaborate on @yyx990803 and @sirlancelot's answers with a bit more detail for people landing on this page looking for quick answers. Take the following code as an example (preview at https://jsfiddle.net/yd2Lpcf1/4/): <div id="app">
<div>
<div v-if="!person">Loading</div>
<div v-else>Hi {{person.name}}</div>
<layout :loading="!person">
Hi {{person.name}}
</layout>
</div>
</div>
<template id="layout">
<div>
<div v-if="loading">Loading</div>
<slot v-else></slot>
</div>
</template> Vue.component('layout', {
template: '#layout',
props: ['loading']
});
new Vue({
el: '#app',
data() {
return { person: null }
},
mounted: function () {
setInterval(() => {
this.person = this.person ? null : {name: 'John'}
}, 1000)
}
}); When this is run in the fiddle linked above then the preview will be blank for a second, then "Hello John" will be shown twice. If run in its own page, then the error console will show the error Following @sirlancelot's recommendation, the only thing that needs to change is to nest an extra <layout :loading="!person">
<template #default>
Hi {{person.name}}
</template>
</layout> When the page is re-run then the preview will show "Loading" twice, for a second, and then "Hello John" will be shown twice, and these values will change every second. The error console will be blank. This demonstrates that the slot is lazily evaluated following the expected In short, when you're using a component with a conditional slot like As an aside, if support for Vue 2.0 is expected to continue for much longer, I would recommend updating the documentation for slots with a section on the "Eager Evaluation" caveat and how it can be solved using the |
https://forum.vuejs.org/t/check-if-components-slot-is-empty/6015/4 |
looks like at least vue 3.2.19 is lazy. |
Version
2.5.16
Reproduction link
bbugh/v-if-slot-issue@ffd6d47
Steps to reproduce
Create a child component with a conditional slot:
Use the slot in a parent component, using code that should not be called when
v-if
resolves asfalse
:Observe that slot code is called, and fails because "example" is an empty object.
A runnable demo of this is in the linked repository.
What is expected?
The behavior is expected to match
v-if
's behavior in other circumstances, which is that the code in theif
block is not evaluated when the conditional check resolves as false.What is actually happening?
The parent slot code is always evaluated, regardless of the value of
v-if
in the child component.The text was updated successfully, but these errors were encountered: