Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load component dynamically based on url parameters in nuxt

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.

like image 629
Imre_G Avatar asked Jul 16 '18 09:07

Imre_G


2 Answers

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.

like image 100
Imre_G Avatar answered Oct 23 '22 10:10

Imre_G


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>
like image 35
dzcpy Avatar answered Oct 23 '22 10:10

dzcpy