skip to Main Content

I am trying to convert a next.js app(https://medium.com/strapi/how-to-create-pages-on-the-fly-with-dynamic-zone-8eebe64a2e1) to a nuxt.js app. In this app I can fetch data from an API and the next.js app uses the APIs data to generate new pages with its corresponding content. Works well in Next.js.

The data/content from the API consists of Seo data for the page, some static values and very important of blocks. These blocks have an attribute called __component where the components name is saved and also have the components data like images, text, etc. So I only have to deal with next.js when adding new components.

In next.js I used the catch-all-route ./pages/[[…slug]].js to catch any slug an user may enter. Then the API is fired with the slug from the context.query and I get back the pages data if it exists. Now the APIs json data only needs to be passed to the blockmanager component.

const Universals = ({blocks}) => {
return <div><BlockManager blocks={blocks}></BlockManager></div>;
};

Here the blockmanager gets the json list of blocks, from which to parse the components.

import Hero from '../../blocks/Hero';
import Pricing from '../../blocks/Pricing';

const getBlockComponent = ({__component, ...rest}, index) => {
    let Block;

    switch (__component) {
        case 'blocks.hero':
            Block = Hero;
            break;
        case "blocks.prices":
            Block = Pricing;
            break;
    }

    return Block ? <Block key={`index-${index}`} {...rest}/> : null;
};

const BlockManager = ({  blocks  }) => {
    return <div> {blocks.map(getBlockComponent)} </div>;
};

BlockManager.defaultProps = {
    blocks: [],
};

export default BlockManager;

How can I replicate this line now in nuxt js?

return Block ? <Block key={`index-${index}`} {...rest}/> : null;

How to return a component/component-tag dynamically in vue/nuxt ?
Is there maybe another solution to automatically insert the wanted component?
Maybe someones knows ho to convert the blockmanagers logic to vue/nuxt logic entirely.

2

Answers


  1. Chosen as BEST ANSWER

    Ok I think I got it. No strange stuff actually. I thought about it too complicated. Wanted all dynamically created but no need as I saw later ...

    <template v-if="blocks">
        <div id="example-1">
            <div v-for="({__component, ...rest}=block, i) in blocks" :key="i">
                <Hero :data="rest" v-if="__component === 'blocks.hero'"/>
                <Pricing :data="rest" v-if="__component === 'blocks.pricing'"/>
            </div>
        </div>
    </template>
    
    
    <script>
        import Hero from '../../blocks/Hero/Hero.vue';
        import Pricing from '../../blocks/Pricing/Pricing.vue';
    
        export default {
    
            components: {
                Hero, Pricing
            },
            props: {
                blocks: Array
            }
        }
    </script>
    

  2. I think you’re looking for the is attribute. You can read about it here.

    Your template would look like:

    <component
      :is="__component"
      key={`index-${index}`}
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search