vuejs / core

đź–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
46.59k stars 8.17k forks source link

Failed to resolve component #3588

Closed Guervyl closed 3 years ago

Guervyl commented 3 years ago

Version

3.0.0

Reproduction link

https://github.com/Guervyl/vuejs3-Failed-to-resolve-component

Steps to reproduce

Clone the repo, install the dependencies and run the project. lick on the plus button and take look at the console. You should see the warning.

What is expected?

I expected it to show new components.

What is actually happening?

It does not show the inner component and it throws a warning in the console.


I have a two components. Each has reference to the other. VueJs return a warning "Failed to resolve component". It shows the first component but, it did not show the inner component.

Here is the full warning so, that you can understand:

[Vue warn]: Failed to resolve component: Binding 
  at <ApiBinding> 
  at <Binding>
  at <App>

Binding has a component and ApiBinding has a component Binding.

The ApiBinding component will rendered if the user select to render it from the Binding component. And from the Binding component another ApiBinding component will be render if the user choose to render a new one. It's like a loop. And there is no problem with this logic because they depend to each other.

Why did I do it like that?

Imagine, in your code you want to make an Api (A) request. This Api request need a query parameter. This parameter, you want to fetch it from another Api (B). That api (B) needs a parameter value from another Api (C). This the logic of my vuejs components.

LinusBorg commented 3 years ago

You have a ciruclar dependency between two ES module imports. Here's workarounds from the Vue 2 docs, that appy similarly to Vue 3:

https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components

Thew noteworthy difference is that for the dynamic import variant of the solution you have to use defineAsyncComponent:

components: {
  TreeFolderContents: () => defineAsyncComponent(import('./tree-folder-contents.vue'))
}

@vuejs/docs The v3 docs are missing this chapter currently.

Guervyl commented 3 years ago

Thanks for your quick answer and resolving my problem. Your example returned an error. The correct way is:

components: {
    TreeFolderContents: defineAsyncComponent(() => import("./tree-folder-contents.vue"))
 }
Guervyl commented 3 years ago

From https://v3.vuejs.org/guide/migration/async-components.html#introduction