Vue’s first-class support for asynchronous components is great, but not everyone is aware of how to show when an async component is loading or has failed to load. So let’s take a look at how to display error or loading components while we’re waiting for an asynchronous component to load.
Start a simple Vue project with vue-cli and the webpack-simple template.
We’ll be using a dynamic import function that Babel doesn’t support by default, so you’ll need to quickly add a small Babel plugin to get the project to build.
# Yarn
$ yarn add babel-plugin-syntax-dynamic-import -D
# NPM
$ npm install babel-plugin-syntax-dynamic-import --save-dev
Go ahead and edit .babelrc
to add that plugin real quick.
{
"presets": [
["env", { "modules": false }],
"stage-3"
],
plugins": ["syntax-dynamic-import"]
}
Now let’s go ahead and create three very complex components next to App.vue.
AsyncComponent.vue
is what we’ll be loading asynchonously.
<template>
<p>Ohai! I'm an asynchronously-loaded component!</p>
</template>
AsyncLoadError.vue
is what we’ll display if something goes terribly wrong.
<template>
<p>Oh noes! I was unable to load the asynchronous component. Cry face. :'(</p>
</template>
AsyncLoading.vue
will display while AsyncComponent.vue
is loading.
<template>
<p><em>Loading noises</em></p>
</template>
Now, in App.vue
, load the utility components as normal, but use the dynanmic import() syntax for AsyncComponent.vue. This function returns a promise that resolves with the actual data when the network request finished.
Then, register AsyncComponent
using an arrow function that returns a configuration object. This object specifies what components to use for loading and error states, and how long to wait before considering the component as having failed to load.
You should now be able to use <async-component></async-component>
in your app!
<template>
<div id="app">
<img src="./assets/logo.png">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
<li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
<li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
</ul>
<async-component></async-component>
</div>
</template>
<script>
import AsyncLoadError from './AsyncLoadError.vue'
import AsyncLoading from './AsyncLoading.vue'
const AsyncComponent = import('./AsyncComponent.vue')
export default {
components: {
AsyncComponent: () => ({
// The component we want to load.
component: AsyncComponent,
// The component to use as a placeholder while the
// async component is loading.
loading: AsyncLoading,
// The component to render instead if there is an error
// loading the async component.
error: AsyncLoadError,
// The delay before the loading component is shown.
delay: 100,
// If this timeout is reached, the async component is considered
// to have failed loading.
timeout: 3000
})
},
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
If you open your browser’s developer tools, you should notice that the asynchronous component is loaded from a different file from the rest of your app. You probably won’t notice the loading and error states unless something goes wrong or you have a very slow network connection, but they will work as well.
TIP: You can test the error state by setting timeout
to 0
in the async component configuration object.
That should be all you need!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!