#Dynamic component not rendering

1 messages · Page 1 of 1 (latest)

sharp rock
#

I have a very simple component. It receives an an array prop and it should render each component in specified by a key

<template>
  <div v-for="(element, i) in builder" :key="'builder-' + i">
    <div>
      <component :is="getComponent(element.acf_fc_layout)" />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    builder: {
      type: Array,
      default: () => [],
    },
  },
  methods: {
    getComponent(component) {
      return 'builder-' + component
    },
  },
}
</script>

I put all my components inside ~/components/builder/xxxx.vue

getComponent return the string correctly and using it directly works with no issues> is there a workaround to make this work?? it's weird because this used to work in Nuxt 2!

livid hatch
sharp rock
livid hatch
#

is your component name /components/builder/BuilderHeader.vue?

sharp rock
#

it is builder/header.vue

livid hatch
#

I suppose maybe this is not possible and dynamic component names must be statically available.

#

Ah yeah so in nuxt3 its suggested to name the component as it will be named with the prefix, try to rename it to builder/BuilderHeader.vue

#

or builder-header.vue

#

This is how I do it: You see I am statically writing out all component names:

<template>
    <component
        v-if="dynamicComponent"
        :is="dynamicComponent"
        v-bind="{ attributes, innerBlocks, mediaItemsStorageKey }">
        <slot />
    </component>
</template>

<script lang="ts">
    export type RichtextItem = {
        id?: ItemBase['id']
        name: ItemBase['name']
        block?: BlockDefault
        innerBlocks?: InnerBlocksDefault<RichtextItem>
    }

    //
</script>

<script lang="ts" setup>
    import type { InnerBlocksDefault, BlockDefault, ItemBase, RichtextPropsMinimum } from '@/types'

    const components = {
        'core/button': resolveComponent('RichtextCoreButton'),
        'core/buttons': resolveComponent('RichtextCoreButtons'),
        'core/code': resolveComponent('RichtextCoreCode'),
        'core/column': resolveComponent('RichtextCoreColumn'),
        'core/columns': resolveComponent('RichtextCoreColumns'),
        // ...
    }

    const props = defineProps<{
        name?: string
        item: RichtextItem
        mediaItemsStorageKey: RichtextPropsMinimum['mediaItemsStorageKey']
    }>()

    const dynamicComponent = components?.[props.item.name as keyof typeof components]
    const attributes = computed(() => props.item?.block)
    const innerBlocks = computed(() => props.item?.innerBlocks)
</script>

sharp rock
#

oh i see. so in my case i need call resolveComponent on every component in my builder directory?

#

nuxt 3 fails me so much man 😣

livid hatch
#

has renaming worked?

#

since your asking for 'builder-' + component and the name of the file is header.vue

livid hatch
sharp rock
#

the renaming didn't work

#

I also tried other component i have such as TheFooter

#

it's directly in ~/components/

livid hatch
#

hm okay yeah then maybe you have to do it like me, importing all components manually with resolveComponent and then select the one you want dynamically from that object

#

One thing, have you logged element.acf_fc_layout to see that it's actually returning the string header?

sharp rock
livid hatch
#

Alright, then it maybe has to go this way. Let me know if you got it work with my method

#

From the docs:

If you are using resolveComponent to handle dynamic components, make sure not to insert anything but the name of the component, which must be a string and not a variable.

#

😄 😄

sharp rock
#

oh ok. this is terrible 🥲

#

it work with vue 3

#

I think it's related to how nuxt imports components

livid hatch
#

yeah nuxt components are different than vue

#

Why terrible?

#

You just have to list them once

sharp rock
#

imagine you have +100 components

#

or if you rename one

livid hatch
#

I got you it's not perfect

#

But I didn't implement it so... 😄 Yeah we have to deal with it. It doesn't work because nuxt has to know on build time which components it needs and which don't

#

With variables it cannot know since they are coming from your DB

sharp rock
#

i kinda refuse to think thats how it intended to work lol
because nuxt have an option to in the components nuxt option to set a directory as global
i feel like if it's set to true, it should be technically possible to render a component in a variable

#

but i guess yeah it's not perfect

livid hatch
#

I get what you mean

sharp rock
#

the issue you sent is open so i guess there's still hope

#

I think, it's just nuxt 2 was too perfect

#

they made the bar so high

livid hatch
#

yeah, just comment there your current issue you have, as more people have this issue as more important it will be

#

yeah but it had a lot of problems