Auto imports and `<component :is="" />`
I'm struggling with a dynamic part of our app, where we load components based on what button a user clicks. Pretty straightforward, but we use constants with types a lot to make things easy, but I can't figure out how to do it with dynamic components.
Pseudo-code:
I'm wondering what a sane approach is here, but so far I'm just running into type issues 😦
15 Replies
Hi @Reinier Kaper. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
You're on the right track with using auto-imported components and dynamic rendering in Nuxt. However, there are some important caveats and best practices to be aware of:
Key Points from Nuxt Docs
- Auto-imported components from
~/components can be used directly in templates, and you can also import them explicitly from #components in your scripts if you need to reference them as variables or pass them around in code [Nuxt Components Directory].
- When using <component :is="...">, you can pass either:
- The component's name as a string (if it's globally registered or auto-imported).
- The actual component object (imported from #components).
TypeScript and Constants
If you want to use constants and types for your components, you should import them explicitly from #components and use those references in your code. This allows you to maintain type safety and avoid issues with string-based component names.
#### Example Approach
constants/calendars.ts
Child Component
Parent Component
Important Notes
- You must import components from #components to use them as variables. Relying on auto-imported names as variables (without explicit import) will not work, as auto-imports are for template usage, not for variable assignment in script [Direct Imports].
- TypeScript: By importing from #components, you get proper typings and can use them in your constants and types.
Summary
- Use explicit imports from #components for variable-based dynamic components.
- Use string names only if you rely on global/auto-imported components and don't need to reference them as variables.
- Your approach with constants and types is correct, just ensure you use explicit imports for the components.
If you need to use dynamic imports or lazy loading, you can also use the Lazy prefix or dynamic import syntax, but for your use case, explicit imports from #components are the most type-safe and maintainable solution [Nuxt Components Guide].
If you have further issues with TypeScript types, please provide the specific error message for more targeted help!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@277205807937093633> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
I don't understand what you're asking, you're having ts error? if so, where?
I actually just solved it!
I was looking to map dynamic components so I can use the references a sa const, whilst also use it to actually mount them.
hmm, the nuxt way would be
const CalendarPreferences = resolveComponent('CalendarPreferences')
you probably don't need the component map too
Interesting, let me try that
That doesn't work, it doesn't actually mount the component that way
Even though the docs tell me this works 🤷♂️
Ah, it doesn't work using a constant mapping 😦
Probably because it injects the code at build-time, liek Daniel explains in his video
Argh
even if you use the
resolveComponent in the component map?Yeah, it doesn't correctly use it unfortunately
It only works if I use it directly in the parent component as a map, but not when it's outside of the file
weird, I did try locally
oh, I did try in the component, let me try outside
[Vue warn]: resolveComponent can only be used in render() or setup(). 😐
So I guess I just have to pre-resolve them in the parent and map them
This is the only way I can get it to work:
Not super elegantother way would be registering them as global components
Yeah I've thought about that as well
I think this is fine for now
At least it's in one location, so not the worst approach and I still have a global const I can use
Why not import them from
#components ?