Skip to main content
  1. Posts/

How to show a loading icon before data is loaded in Vue and Vuex

·665 words·4 mins
Joe Erickson
Author
Joe Erickson
Senior software developer specializing in web development, AI, and helping others learn to code.

UPDATE: I have a better way of handling this here. I would recommend that post if you’re looking to handle the status of your data loads from now on.

I hate ambiguous lag. Is this site still loading or did it freeze? Am I waiting for something or is this it? Whenever a website has to load in information from an API, there is a chance that loading will appear painfully slow to the user. Human beings perceive an empty screen much differently than they perceive an animation on the screen.1 In order to make our website seem faster than it is, it’s always good to throw in a loading animation every time that we have to access a potentially slow resource like an API call.

Applications built in Vue have this same issue, but Vue gives us a number of tools to handle this very gracefully. This article will show a way to handle loading icons that make showing and hiding the icons very simple. If you’re following the methods for loading data from APIs that I laid out in How to query your API using Vuex in your Vue application that will make this even easier.

Getting a loading icon
#

First step is to get a loading icon for your site. I downloaded one from Preloaders.net - Circular (Spinners). I made this one for this exercise:

Loading icon from icons8.com

I’ll be using an svg spinner, but you can use whatever icon you want that is supported by the browsers you’re targeting.

Adding the icon to the component
#

To add the icon to the component, we can just add a v-show to the location where the data we are loading in will be located. Before the data is loaded, we will show the spinner. Once the data is loaded, we can hide the spinner and show the data table.

In my example below, I’m using the user table that I showed off in the article on loading data via an API into Vuex.

You can look at the code for this example at https://codesandbox.io/s/using-loading-icons-in-vuex-36jh6

In the Vuex store, we defined the initial state of the users array to be an empty array:

state: {
  users: []
},

If the users state variable is empty, then that means we haven’t loaded in the data yet. So we can set up our UI in our component like this:

<div v-show="users.length == 0">
  <img src="./../assets/loading icon.png">
</div>
<table class="users" v-show="users.length != 0">
  <tr>
    <th>Name</th>
    <th>Username</th>
    <th>Email</th>
  </tr>
  <tr v-for="user in users" v-bind:key="user.id">
    <td>{{user.name}}</td>
    <td>{{user.username}}</td>
    <td>{{user.email}}</td>
  </tr>
</table>

So if the users data property is empty, show the loading icon. Otherwise, show the table. And once we map in the users state variable from Vuex:

computed: {
  users() {
    return this.$store.state.users;
  }
},

Then the loading icon will show up before the data can be loaded. This goes a long way in letting a user know that we’ve got this handled. They can see that we have anticipated that this data may take time to load and that they just need to wait a hot second before the table will show up.

This is great if the data load is being called from a created() method, but what if the user requests a reload of the data or you need to otherwise pull data from the server again?

One thing you can do is to blank out the users state variable by calling this.$store.commit('SAVE_USERS', []);. This will again show the loading icon and then you can call this.$store.dispatch("loadUsers"); again to get the new data.

This is a very easy way to show a loading icon for users. It might not work for every situation you have, but covers a lot of the common use cases that front-ends have for letting the user know that a data load is in progress.


  1. For more interesting information on human perception of time and web applications, take a look at this Smashing article: Why Performance Matters, Part 2: Perception Management — Smashing Magazine ↩︎

Related

How to save data to your API using Vuex

·603 words·3 mins
I talked before about how to query your back-end API from Vuex, but that was mainly centered on getting data. What happens when you want to save data to a back-end API after it is updated or added in the Vuex store? What’s the best, most efficient way to accomplish this?

What's the purpose of Vuex?

·679 words·4 mins
There are a lot of things to worry about when it comes to Vue applications. You’ve got SPAs and routing and web workers and Jest and Cypress and everything else. It gets overwhelming pretty quickly. The hard part is not learning these technologies, it’s knowing what their place is in the application.

How to query your API using Vuex in your Vue application

·866 words·5 mins
Once you start using Vuex to manage the shared data of your Vue application, it becomes less clear on where or how to call your back-end API. I think everyone starts out making API calls in the created function of your component. But that doesn’t scale past a handful of components. Then, they end up loading in the same data over and over again and each component has it’s own copy, which is impossible to keep in sync. You lose the efficiency of having one part of the system in control of the data when you do that and on a larger application, this very quickly falls apart.

Should you always use getters in Vuex?

·1166 words·6 mins
One of the questions that comes up time and again concerning Vuex is “Do I always use a getter when accessing data? Or can I directly access the raw state?” It’s one of those things you hear about that you should do, but no one seems to really explain why. And do you really need to create a getter for every single piece of data that you put in the store? Isn’t that just a bunch of unneeded boilerplate and duplication?