Skip to content

Vue warns incorrectly if component is surrounded by functional component #3257

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

Open
plehnen opened this issue Feb 18, 2021 · 4 comments
Open
Labels
🧹 p1-chore Priority 1: this doesn't change code behavior. 🐞 bug Something isn't working

Comments

@plehnen
Copy link

plehnen commented Feb 18, 2021

Version

3.0.5

Reproduction link

https://codesandbox.io/s/vue3-slot-invoked-outside-warning-demo-ezuud

Steps to reproduce

Please have a look at the minimal reproduction.

As soon as I create a component inside of a "functional component", it show's a warning.

What is expected?

It shouldn't warn.

What is actually happening?

[Vue warn]: Slot "default" invoked outside of the render function: this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.


The warning is only shown if I create the watch in MyComponent.vue (or if I access isMandatoryOrSlotVisible.value directly.)
If I use the same code without the surrounding MyContainer component, it work's without any warning. Since there is no invokation of the slot function in the surrounding MyContainer component, the warning is misleading.

@plehnen plehnen changed the title Vue warns incorrectly if I surround my component in a functional component Vue warns incorrectly if component is surrounded by functional component Feb 18, 2021
@posva posva added 🐞 bug Something isn't working 🧹 p1-chore Priority 1: this doesn't change code behavior. labels Feb 18, 2021
@HcySunYang
Copy link
Member

Is this really a bug? I do not think so. As long as you execute the slot functions in setup, you will get this warning, which has nothing to do with whether you use functional components to wrap it.

import { createApp, h, defineComponent } from 'vue'

const Comp = defineComponent({
  setup(props, { slots }) {
    // a warning raised, this is as expected
    const s = slots.default && slots.default()

    return () => s
  }
})

createApp({
  setup() {
    return () => h(Comp, () => 'sss')
  }
}).mount('#header')

@plehnen
Copy link
Author

plehnen commented Feb 19, 2021

@HcySunYang But then I should get the warning too when I execute the MyComponent directly in App.vue (instead of MyContainer), right? But then there is no warning. so something seems to be wrong there...

A little bit of context of the bigger picture what I try to accomblish: I want to tell the parent component if any of the child components are considered "empty" (based on their data AND slot content). In vue2 those slots where just empty when no element was rendered (with functional components), but since vue3 I can't tell if the component has a v-if="false" on the root element. I just see the an array with the components or in some cases an entry of type "Symbol(Comment)" ($el is not accessible).
So I guess I have to use provide and inject. But those need to be performed in setup (and not in render). So there seems to be no other way to invoke the slot function in setup, to determine if there is something to show.

@HcySunYang
Copy link
Member

Ok, I made a PR to make the warning consistent when calling the slot function outside the render function.

However, more and more users request similar capabilities. They hope to call the slot function in the setup function to determine whether the slot content exists or meets expectations. Maybe we don’t need to report that warning message, but instead, emphasize it in the document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧹 p1-chore Priority 1: this doesn't change code behavior. 🐞 bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants