Subscribe on changes!

Local components aren't rendered when used within slots

avatar
Oct 29th 2020

Version

3.0.2

Reproduction link

https://github.com/iamthefreeman/vue-3-slot-component-issue

Steps to reproduce

We are currently migrating to Vue 3 from Vue 2 where we use a lot of Laravel server-rendered inline-templates. After reviewing documentation we decided on going down the route of slotted components.

One of the issues that we have now is that we have components that aren't registered globally but registered on the top-level component but when we try to access the local components they aren't being parsed by Vue.

I have attached a repo which reproduces my issue.

What is expected?

Repo, should produce the following output:

Slot content: Global component Local component

What is actually happening?

Repo, only produces the following output:

Slot content: Global component

avatar
Oct 29th 2020

This is expected behaviour. It's the same in Vue 2. If you want to use a component in your runtime compiled template, it has to be globally registered. Local is not registered. It doesn't matter if it's registered in wrapper. That would only allow you to use the component inside wrappers template. The slot is not considered to be its template.

avatar
Oct 29th 2020

@cathrinevaage is one the right track but this is unrelated to "runtime compiled templates".

The point is that you essentially made the content of #app to be the template of the (unnamed) root component that you passed to createApp (let's call this component App) for better reference).

App passes the slot content to Wrapper, so Local has to be locally registered in App, the source component that the slot content is coming from, not Wrapper, which is receiving the slot content.

const app = Vue.createApp({
  components: {
    Local: require('./components/Local.vue').default
  }
});

@cathrinevaage is right in that this is the same behavior as in Vue 2, and it makes sense:

  • Components that do receive slots should have to know about the types of components the slots might or might not receive.
  • The parent component which is sending the slot content down, on the other hand, knows very well which components are being used, and so it's that component's responsibility to have them registered, locally or globally.

I understand that this might be a challenge in your specific setup. Visit chat.vuejs.org and ask the community for help, there's lots of people running similar setups to yours.