4
votes

I use Vue 3 and I have a dynamic component. It takes a prop called componentName so I can send any component to it. It works, kind of.

Part of the template

<component :is="componentName" />

The problem is that I still need to import all the possible components. If I send About as a componentName I need to import About.vue.

Part of the script

I import all the possible components that can be added into componentName. With 30 possible components, it will be a long list.

import About "@/components/About.vue";
import Projects from "@/components/Projects.vue";

Question

It there a way to dynamically import the component used?

1

1 Answers

3
votes

I already faced the same situation in my template when I tried to make a demo of my icons which are more than 1k icon components so I used something like this :

<script>
import {defineAsyncComponent,defineComponent} from "vue";

const requireContext = require.context(
    "@/components", //path to components folder which are resolved automatically
    true,
    /\.vue$/i,
    "sync"
);
let componentNames= requireContext
    .keys()
    .map((file) => file.replace(/(^.\/)|(\.vue$)/g, ""));

let components= {};

componentNames.forEach((component) => { //component represents the component name
    components[component] = defineAsyncComponent(() => //import each component dynamically
        import("@/components/components/" + component + ".vue")
    );
});
export default defineComponent({
    name: "App",
    data() {
        return {
            componentNames,// you need this if you want to loop through the component names in template
         
        };
    },
    components,//ES6 shorthand of components:components or components:{...components }

});
</script>

learn more about require.context