Loading Components Asynchronously in Vue.js

Sometimes you need to load components while the app is already running. This can be because you have so many components that it will be too cumbersome to load all of them or maybe the shape of some component is not known in advance. With Vue, you can load components only when they have to actually render. Next time the component will need to be rendered, it will be retrieved from cache.

You want to load your component asynchronously only when you already know how to make AJAX requests with Vue. In this article, though, we will skip those, so you can follow along right away.

Let’s Start

Let’s suppose that we have a big vase e-commerce. We have one component for every vase, but we can’t give them all to the user at once. It will be too much data. We will load the component from the Internet.

As only modification, we will simulate the AJAX call with a simple setTimeout. Let’s go back to our favorite online editor, JSFiddle:

Vue.component('XuandePeriodVase', (resolve, reject) => { 
  setTimeout(() => { 
    if ((new Date()).getDay() !== 6) { 
      resolve({ 
        template: '<div>Car Buy for only 4000000</div>', 
        mounted () { 
          this.$parent.$emit('loaded') 
        } 
      }) 
    } else { 
      reject("Today is Sunday, Internet is closed!") 
    } 
  }, 1000) 
})

Our Vue instance will hold only one variable to display the (simulated) loading of the component:

new Vue({ 
  el: '#app', 
  data: { 
    loading: true 
  }, 
  created () { 
    this.$on('loaded', () => { 
      this.loading = false 
    }) 
  } 
})

Put a little loading message along with the vase component and you’re done:

<div id="app"> 
  <span v-if="loading">loading...</span> 
  <xuande-period-vase></xuande-period-vase> 
</div>

When you load the page, you will see your component appear after 1 second, in which a real AJAX call will be happening. If it’s Sunday, you will see a sorry message in the console; that will represent the case when the component can’t be loaded because of network problems.

How it works

The syntax for asynchronous component, therefore, is as follows:

Vue.component('comp-name', (resolve, reject) => { ... })

Instead of passing an object as a second argument, we are actually passing a function with two arguments. The first is a function that you will have to call once the component (more precisely, the object that contains the properties of the component) is available. The second is another function that accepts a string. When Vue is not working in production mode, the string will be displayed in the console. You can have several reasons why the component is not working, such as an actual timeout or a connection error:

if (response.status > 400) { reject('4XX error received') } 
setTimeout(() => { reject('connection timeout') }, 5000)

Another feature of our code is that while our components load, even if normally the operation should take less than a few hundreds of milliseconds, we would like a courtesy message or graphics to improve user experience.

To achieve that, we are emitting a loaded message when the component is mounted:

mounted () { 
  this.$parent.$emit('loaded') 
}

Whoever the parent is can now receive the message and act upon it (or not). In our case, we pick up the message and turn off the loading message:

created () { 
  this.$on('loaded', () => { 
    this.loading = false 
  }) 
}

Muhammad Mubeen

Muhammad Mubeen

Mubeen is a full-stack web & mobile app developer who is very proficient in MEAN.js, Vue, Python, Ionic 4, Flutter, Firebase, ROR, and PHP. He has created multiple mobile and web applications. He is very passionate about sharing his knowledge.

Leave a Reply

Your email address will not be published. Required fields are marked *

Trending