logo

Show A Loading Spinner In Nuxt.js

Kenneth Jimmy

1/23/2021

Alright, you created a fantastic animation in your Nuxt app which is supposed to come into play and manipulate some opening contents of the home page as soon as it gets loaded. However, the contents of your page, which are supposed to be hidden until the animation starts playing, are already showing. Then they disappear, and only then reappear in style as you programmed them to do. Gosh! 😱 That's weird! What's happening?

Well, you probably should show a spinner screen that will last as long as the home page is loading so that your JavaScript can have all the time it needs to present your awesome intro scene. Let me show you how to do it in a Nuxt app.

Take Advantage of Vue lifecycle hooks

Vue lifecycle hooks are the reserved methods that get executed in a certain stage of the Vue object lifespan. Starting from the initialization to when it gets destroyed, the object follows different phases of life. Below is a popular diagram indicating the hook sequence:

Img

As you can see in the diagram, Vue has up to 8 lifecycle hooks, namely:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

So, we could use one of them to simply solve our problem here. If you could guess, which one of them could help us achieve our goal? Yeah, you guessed right! beforeCreate() 😎

If you want to learn more about Vue lifecycle hooks, check out 👉 vue docs.

The implementation logic is straightforward:

Create a component and name it whatever you like. In my case, I'll name it LoadSpinner.vue. The component should contain the div element and css code for styling your spinner as shown in the following code snippet. You can find other samples here.

<template>
  <div class="splash-screen">
    <div class="spinner-wrapper">
      <div class="spinner"></div>
    </div>
  </div>
</template>

<style scoped>
.splash-screen {
   background: #f2f0ee;
    width: 100vw;
    height: 100vh;
  position: fixed;
  z-index: 50;    
}

.spinner-wrapper {
  position: absolute;
  left: 50%;
  top: 50%;

  transform: translate(-50%, -50%);
}
.spinner {
  width: 80px;
  height: 80px;
  margin: 100px auto;
  background-color: #e45447;

  border-radius: 100%;
  -webkit-animation: sk-scaleout 1s infinite ease-in-out;
  animation: sk-scaleout 1s infinite ease-in-out;
}

@-webkit-keyframes sk-scaleout {
  0% {
    -webkit-transform: scale(0);
  }
  100% {
    -webkit-transform: scale(1);
    opacity: 0;
  }
}

@keyframes sk-scaleout {
  0% {
    -webkit-transform: scale(0);
    transform: scale(0);
  }
  100% {
    -webkit-transform: scale(1);
    transform: scale(1);
    opacity: 0;
  }
}
</style>

Open your /layouts/default.vue file and paste the following snippet inside the <script> tag.

<script>
export default {
  beforeCreate() {
    this.showHideSpinner = true;
  },
  mounted() {
    this.showHideSpinner = false;
  },
  data() {
    return {
      showHideSpinner: true
    };
  }
};
</script>

Inside the data() method, we initialize a variable called showHideSpinner and set it's value to true. Then, in beforeCreate() method, we set this.showHideSpinner to true. This means that the spinner will be visible at first and continue to show until the mounted() hook is called where the value of this.showHideSpinner becomes false and the spinner disappears.

Now that we have the script ready, let's plug our component and pass v-if="showHideSpinner" in. Paste the following code as first child of the container div.

/layouts/default.vue

<template>
  <div>
    <LoadSpinner v-if="showHideSpinner" />
    
    //...
    
    <Nuxt />
  </div>
</template>

And there you have it! Enjoy the rest of your day. ✌

Conclusion

The important thing to note is that the vue lifecycle hooks is a very powerful tool that we can use to solve problems in a much simpler and easier way. A splash screen (so to speak) is one of many incredible things you can do with Vue lifecycle hooks.