Dynamic Importing Component Templates with Vue.js

One of the really cool features of Vue js is to dynamically load components. Let’s look at some of the examples of components.

Components are basically reusable code that can be used across multiple pages. If you try to add the same code for multiple pages then it becomes an absolute mess.

Let’s say I have the Folder structure like

components
  animations
    robust-animation-1.vue
    robust-animation-2.vue
    maybe-like-15-more-of-these.vue
  headings
    heading2.vue
  SectionHeader.vue
pages
  index.vue

SectionHeader is the component from which the components are dynamically loaded based on props.

Probably most people would import all the components and then use the <component> tag with :is attribute. You can read Dynamic Component documentation.

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

This is just a normal way to use dynamic components but it still contains unnecessary import of components. So what we can do is to use dynamic imports from Webpack. Used together with computed values this is where the magic happens–yes, computed values can return a function.

Example

computed: {
            stepComponent(componentname) {
                let data = componentname;
                return () => import(`./animations/${data}`);
            }
        },

Index.Vue

<section-header post-title="Menu" class-name="menu" canvas="./animations/robust-animation-1">
</section-header>
  <script>
    import SectionHeader from "../components/SectionHeader";

    export default {
        name: 'PageIndex',
        components: {SectionHeader}
    }
  </script>

SectionHeader.vue

<template>
  <div>
    post_title {{postTitle}}
    <br/>
    class-name {{className}}
    <br/>
    canvas {{canvas}}
    <br/>
    <heading2 post-title="postTitle"></heading2>
    <br/>
    <component v-bind:is="stepComponent"></component>
  </div>
</template>

<script>
    import Heading2 from "./headings/heading2";

    export default {
        name: "SectionHeader",
        components: {
            Heading2,
        },
        props: ['postTitle', 'className', 'canvas'],
        computed: {
            stepComponent() {
                let data = this.canvas.split('/')[2];
                return () => import(`./animations/${data}`);
            }
        },
    }
</script>

robust-animation-1.vue

<template>
  <div>
    From - robust-animation-1
  </div>
</template>

<script>
    export default {
        name: "robust-animation-1"
    }
</script>

Conclusion

  • So the first thing is it’s asynchronous. Components are dynamically loaded base on props that you want.

  • No unnecessary import of components. Dynamically importing components that you want.

  • It keeps your code clean

If you have any feedback please leave a comment below. Please clap for this article. Thanks for reading.

Update (Vue 3)

For Vue 3 you need to use defineAsyncComponent method.

import { defineAsyncComponent } from 'vue'

defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

Did you find this article valuable?

Support Pratik Patel by becoming a sponsor. Any amount is appreciated!