N
Nuxt2mo ago
rxsto

How should I use components as values in objects?

I want to simplify and automate the implementation process of a dashboard I'm helping to build, and I am struggling to use imported components as values on objects that are defined by typescript interfaces. Somewhere in the center of the codebase there's a dynamic <component> with the accompanying :is="someValue" attribute. This component tag with its attribute needs to resolve a reactive dynamically passed component which would be part of an object describing the section of the dashboard. This object is defined by a typescript interface as follows:
interface Section {
name: string
...
component: ???
}
interface Section {
name: string
...
component: ???
}
When constructing such a Section object I want to pass along the actual imported component that will then later be rendered via the <component :is="someReactiveValue"> tag. I would collect the components in an index.ts like this:
export { default as DashboardOverviewPage } from './DashboardOverviewPage.vue'
...
export { default as DashboardOverviewPage } from './DashboardOverviewPage.vue'
...
And then later reuse them like this:
import { DashboardOverviewPage } from "~/components/dashboard/sections/"
import { DashboardOverviewPage } from "~/components/dashboard/sections/"
How would I go about doing this properly? I've tried typing the component property of the interface with the DefineComponent type, which didn't really work, since it gave me overload errors, as well as the need to actually export the interface since the file turned into a module. Also: a bonus would be if I could ditch the whole interface thing by aggregating the components I need to render programmatically by collecting the from a specific directory. I haven't yet found a way for doing that properly, but maybe there's is some wizardry built into nuxt that could allow me to collect components as an array from a specific directory. Would appreciate any help! (feel free to ping) :pepoLove:
7 Replies
handshake
handshake2mo ago
do you have a test repo of what you have so far?
rxsto
rxsto2mo ago
i can create a small example repo, yes
rxsto
rxsto2mo ago
this is about the current state the project is in: https://stackblitz.com/edit/github-qacn3f
Oskar Lang
StackBlitz
Nuxt - Starter - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
dwol
dwol2mo ago
maybe try using markRaw? I have a multi-step form im using with <component :is=""> Using pinia to keep track of the current form stage
import { StageInitial, StageForm, StageFinal } from '#components'
type Init = typeof StageInitial
type Form = typeof StageForm
type Success = typeof StageFinal
type Comp = Init | Form | Success

export const useFormStage = defineStore('form-stage', () => {
const currentStage = ref('StageInitial')

const stages: Record<string, Comp> = {
StageInitial: markRaw(StageInitial),
StageForm: markRaw(StageForm),
StageFinal: markRaw(StageFinal)
}
import { StageInitial, StageForm, StageFinal } from '#components'
type Init = typeof StageInitial
type Form = typeof StageForm
type Success = typeof StageFinal
type Comp = Init | Form | Success

export const useFormStage = defineStore('form-stage', () => {
const currentStage = ref('StageInitial')

const stages: Record<string, Comp> = {
StageInitial: markRaw(StageInitial),
StageForm: markRaw(StageForm),
StageFinal: markRaw(StageFinal)
}
Theres some things to watch out for when using markRaw that I cant remember off the top of my head, might want to look into that
handshake
handshake2mo ago
not fully fledged, but using a reactive value for the layout switching seems to help... https://stackblitz.com/edit/github-qacn3f-uzhyxp?file=app.vue You'll have to clean up any errors/warnings
StackBlitz
Nuxt - Starter (forked) - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
Dubem
Dubem2mo ago
This is what I do, It will not solve for the auto-import thing, but you could map the component to string values.
No description
rxsto
rxsto2mo ago
thanks guys, will try a few of your ideas!