Vue: Unknown custom element warning with recursive components, babel

Created on 15 Mar 2018  ·  6Comments  ·  Source: vuejs/vue

Version

2.5.2

Reproduction link

https://github.com/adam-cowley/nestedtest

Steps to reproduce

The repo is based on the webpack template. Run npm run dev to start the project.

What is expected?

I am attempting to reuse components in a nested pattern. The EntityComponent should render a RelationshipComponent which should in turn render an EntityComponent.

What is actually happening?

Although each component is defined with a name property, I receive the following warning in the console and nothing rendered on the page.

Unknown custom element: <EntityComponent> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

If I make a change to the EntityComponent file, it will hot swap in the component which will render without a warning.

I've tried in vain to set keys and a name property on the child element and rename the element. Attempting to alias the component name has also proved unsuccessful.

Removing the component means the rest of the component appears correctly.


This is a barebones reproduction but the final version uses vuex for state management. Each child component has a reference property passed through it, then a getter is used to pull the information for that specific reference from an array in the store. Using 'v-for' on a div will list the relevant array entries so this part works. It seems that the name property is being ignored for the nested component.

I'm struggling to find any documentation on this - possibly due to using the wrong keywords? I'm happy to write a blog post if/when this gets resolved to give others a helping hand.

Most helpful comment

I cannot test right now, but have you seen: https://vuejs.org/v2/guide/components.html#Circular-References-Between-Components?

All 6 comments

name is a component option (like data, methods, etc.), not a prop: https://vuejs.org/v2/api/#name

Yep, I've defined that in the export for both files

export default {
    name: 'EntityComponent',
    components: {
        RelationshipComponent,
    },
    props: {
        name: String,
        children: Array,
    },
}

https://github.com/adam-cowley/nestedtest/blob/master/src/components/EntityComponent.vue#L16

Using name as a prop could be a little confusing, apologies for that. I also tried it as a prop in the original project out of sheer desperation.

I cannot test right now, but have you seen: https://vuejs.org/v2/guide/components.html#Circular-References-Between-Components?

This looks about right (if not a little unintuitive). I must have got frustrated further up the document. I've put the following in main.js and everything is right with the world again.

import EntityComponent from '@/components/retrieve/EntityComponent'
import RelationshipComponent from '@/components/retrieve/RelationshipComponent'

Vue.component('EntityComponent', EntityComponent)
Vue.component('RelationshipComponent', RelationshipComponent)

Thanks for the pointer @posva

How come you have to do this instead of:

export default {
<template>
  <div>foo</div>
</template>
<script>
export default {
  name: 'foo-bar'
}
</script>

I cannot use this component unless I declare it in main.js. If I import it where I want to use it I get the not found error. I have another component I'm using which loads fine.

From the docs:

To explain what’s happening, let’s call our components A and B. The module system 
sees that it needs A, but first A needs B, but B needs A, but A needs B, etc, etc. 
It’s stuck in a loop, not knowing how to fully resolve either component without first
 resolving the other. To fix this, we need to give the module system a point at which 
it can say, “A needs B eventually, but there’s no need to resolve B first.”

If you use components recursively inside other components, Vue will get confused as to which one to resolve first. By defining the components in main.js (ie before the components themselves are rendered) you get around the problem.

If the components aren't used recursively then you can just import them as usual.

Was this page helpful?
0 / 5 - 0 ratings