Home » vue » Vue.js – Dynamic component import in data and computed properties

Vue.js – Dynamic component import in data and computed properties

Posted by: admin November 26, 2021 Leave a comment

Questions:

I have component ‘Page’ that should display a component which is retrieved via its props.

I managed to get my component loads when I harcode my component path in my component data like this :

<template>
  <div>
    <div v-if="includeHeader">
      <header>
        <fv-header/>
      </header>
    </div>
    <component :is="this.componentDisplayed" />
    <div v-if="includeFooter">
      <footer>
        <fv-complete-footer/>
      </footer>
    </div>
  </div>
</template>

<script>
  import Header from '@/components/Header/Header';
  import CompleteFooter from '@/components/CompleteFooter/CompleteFooter';

  export default {
    name: 'Page',
    props: {
      componentPath: String,
      includeHeader: Boolean,
      includeFooter: Boolean
    },
    data() {
      componentDisplayed: function () {
        const path = '@/components/my_component';
        return import(path);
      },
    },
    components: {
      'fv-header': Header,
      'fv-complete-footer': CompleteFooter,
    },
  }
</script>

But with the data I cannot refer to my props within my function as this is undefined.

I tried to used computed properties instead of data but I have the error “src lazy?0309:5 Uncaught (in promise) Error: Cannot find module ‘@/components/my_component’. But the module exists! But maybe not at that time ?

computed: {
  componentDisplayed: function () {
    const path = `@/components/${this.componentPath}`;
    return import(path);
  },
},

There must be away to deal with that but I am quite a beginner to vue.js 🙂

Answers:

Instead of trying to import the component in your child component, instead import it in the parent component and pass the entire component as a prop.

<template>
  <div :is="component" />
</template>

<script>
export default {
  name: "page",
  props: {
    component: {
      required: true
    }
  }
};
</script>

And in the parent

<page :component="component" />

and

import Page from './components/Page';

// and further down

data () {
  return {
    component: HelloWorld
  }
}

Edit Vue Template