Implementing a loading screen in Vue with VueRouter.

Add to bookmarks

Wed May 22 2019

If, you wanted to add a neat loading "screen" to your Vue Spa, A "screen" that would cover the whole viewport while the data for the next screen is being fetched in the background. Something along these lines: loading screen

How it was achieved

I achieved this effect on my portfolio by adding a global boolean to the Vuex store (conveniently named isLoading):

state: {
    isLoading: false,
    ...
  },
  mutations: {
    setLoading(state,loading){
      state.loading = loading;
    },
    ...
  },
  ...

Then in the main Layout component (App.vue in my case), the loading screen/overlay's HTML code was added and attached via a v-if to a computed isLoading property. You can also wrap it in a transition for beauty:

<template>
...
<transition name="loader">
    <loader v-if="computed"/>
</transition>
...
</template>

<script>
...
computed: {
     isLoading() {
        return this.$store.state.isLoading;
    },
    ...
}
...
</script>

This way the loader component is attached to the global isLoading stored in the Vuex store.

Displaying It

In order to control how it was displayed, I used one of VueRouter's global navigation guard beforeRouteEnter on each page that was to show the overlay on load. It is in this method all fetching would be done for the incoming page and also toggling of the isLoading state value.

...
beforeRouteEnter(to, from, next) {
    store.commit('setLoading', true);
    //Fetch all data from server
    store.commit('setLoading',false);
}

Conclusion.

Using VueRouter's navigation guard on components, you can have a more precise level of control on loading behavior of your site for even better UI.

CHEERS!