VueJS 3 Async Component

In a bigger vuejs application, we divide app into smaller components. Sometimes, components are needed to be available right aways however sometimes you may want to load component when its  needed.

Sometimes you may want to load a component asynchronously. There is a special syntax that you can use in order to create async components in VueJs.

Let's take a look at some of the use cases for async component:

  • When you want fetch some server data before app is loaded
  • When some component is not needed to show immediately however we can load them async
  • To improve page load time by loading component async

Just to understand the concept we will create an app which loads async component. Let's look at the following code and then understand it:

Importing defineAsyncComponent

First of all we import defineAsyncComponent function from vue as shown below:

import { defineComponent, defineAsyncComponent } from 'vue';

Now, we will define a constant called LoaderComponent with following defination:

import AsyncError from './components/AsyncError.vue';
import AsyncLoading from './components/AsyncLoading.vue';

const LoaderComponent = defineAsyncComponent({
  // this component renders when error happens
  errorComponent: AsyncError,

  // this component renders when async request is in process
  loadingComponent: AsyncLoading,

  // component that we want to load async
  loader: async () => {
    // adding some delay to show loading component
    await new Promise((resolve) => setTimeout(resolve, 1000));

    // once promise is resolved load our local component
    return import('./components/AsyncComponent.vue');
  },
});

defineAsyncComponent function takes an object as an argument with following keys:

  • errorComponent: the component that we want to show when async request fails
  • loadingComponent: the component that we want to show when async request is happening
  • loader: takes async functions and returns component that we want to load async

Finally, in our app component we will import this newly defined component as shown below:

export default defineComponent({
  components: { LoaderComponent },
  setup() {},
});
</script>

<template>
  <LoaderComponent />
</template>

First we add LoaderComponent to components key then we would add this new component in our template tag. When we run the code we can see that it shows loading first and then it loads our real component data.

This is useful when you want to show user when loading or error state happens while fetching your remote data.

Rather then showing blank screen using loading and error components we can update user about what is happening during the fetch request.

Here is a diagram of what is happening during the request: