3

I have two components, an item component and a folder component. Each item contains it's own folder component, and each folder component contains a list of items.

So I am trying to use the item component in the folder component, and vice versa, however, I am getting the error: unknown custom element: <item> - did you register the component correctly? For recursive components, make sure to provide the "name" option. Despite the fact that I have the name option set on both components. Any ideas?

Code is below

item.vue

<template>
    <div class="item" style="height: 30px">
        . . .
        <folder v-if="item.hasChildren" :id="id"></folder>
    </div>
</template>


<script scoped>
import Folder from './folder.vue';

export default {
    name: 'item',
    props: ['id'],
    components: {
        Folder
    }
};

</script>

folder.vue

<template>
    <div class="folder">
        <template v-for="(child, index) in children">
            <item :last-item="index === children.length - 1" :key="child.id" :id="child.id"></item>
        </template>
    </div>
</template>

<script>
import Item from "./item.vue";

export default {
    name: 'folder',
    props: ['id', 'hasChildren'],
    components: {
        Item
    }
};
</script>
Owen M
  • 2,585
  • 3
  • 17
  • 38

2 Answers2

5

This is probably happening because of the circular referencing between your components ..

When you look closely, you’ll see that these components will actually be each other’s descendent and ancestor in the render tree - a paradox!

To resolve this paradox you can either register your components globally using Vue.component, or you can defer the import of one of your components to a later point (by moving your import to the beforeCreate hook or using async components as demonstrated here) ..

folder.vue

<template>
    <div class="folder">
        <template v-for="(child, index) in children">
            <item :last-item="index === children.length - 1" :key="child.id" :id="child.id"></item>
        </template>
    </div>
</template>

<script>

export default {
    name: 'folder',
    props: ['id', 'hasChildren'],
    components: {
        'item': () => import('./item.vue')
    }
};

</script>
tony19
  • 125,647
  • 18
  • 229
  • 307
Husam Ibrahim
  • 6,999
  • 3
  • 16
  • 28
  • Why should OP use async components? – Phil Nov 07 '18 at 21:46
  • @Phil I'll defer to you on this but in the [docs](https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components) they present it as a solution to circular referencing between components. – Husam Ibrahim Nov 07 '18 at 21:54
  • 1
    That's a great piece of information that should be mentioned in your answer. It gives people a reason to visit the links you provide – Phil Nov 07 '18 at 21:55
0

You need to provide the key (name) in the components object like so,

item.vue

components: {
    folder: Folder
}

folder.vue

components: {
    item: Item
}