13

I have a page in nuxt that is divided in two parts. The first part is a normal template structure filled with dynamic content based on the url param. The second part is a component that should be loaded based on this data. I am trying to accomplish it like this:

<template>
  <div>
    <h1>{{myData.header}}</h1>
    <p>{{myData.text}}</p>
    <my-component></my-component>
  </div>
</template>

<script>
export default {
  components: {
    'my-component': () => import('@/components' + this.myData.component)
  },
  async asyncData(context) {
    return {
      myData: context.params.myData
    }
  }
}
</script>

But this is not working. Is there a way to accomplish this?

I am familiar with the possibility to use <my-component :is="myData.component"></my-component>. However, this requires me to import every component explicitly and I would like to avoid this.

3 Answers 3

19

I found a solution to this yesterday. It needs to be done like this.

<template>
<div>
    <h1>{{myData.header}}</h1>
    <p>{{myData.text}}</p>
    <component :is="componentInstance"></component>
</div>
</template>

<script>
export default {
    computed: {
        componentInstance () {
        const name = this.myData.component
        return () => import(`./components/${name}`)
        }
    },
    async asyncData(context) {
        return {
        myData: context.params.myData
        }
    }
}
</script>

More info in this article: https://itnext.io/vue-a-pattern-for-idiomatic-performant-component-registration-you-might-not-know-about-9f3c091846f5.

Sign up to request clarification or add additional context in comments.

1 Comment

It is working great for one condition but when I want to render components based on conditions, I am getting some issue, stackoverflow.com/questions/72176906/…
2

Based on Imre_G's answer, it can be simplified like this:

<template>
  <div>
    <h1>Hi</h1>
    <p>Hello World!</p>
    <Component :is="component"></Component>
  </div>
</template>

<script>
export default {
  computed: {
    component() {
      return () =>
        import(`../../__relative_path__/${this.$route.params.yourParam}`)
    }
  }
}
</script>

Comments

0

I've found an easy way of doing it if you need to import an existing component. I did it because I'm using Nuxt and I need to load the component only on client side:

<template>
  <my-component></my-component>
</template>

<script>
  data() {
    return {...}
  },
  mounted() {
    if (process.browser) {
      const component = require("~/assets/libs/component");
      Vue.use("my-component", component); // or just Vue.use(component);
    }
  }
</script>

This method avoid the import errors related to Window instance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.