Display a spinner (preloader/loading indicator) each time the page transitions and remove it once all assets have finished loading in Vue Gridsome

I've set up a preloader using Gridsome (Vue static site generator with Vue Router). In my index.html, I added a simple div that covers the entire page. Then, to hide the preloader once everything has loaded, I included this JS code in index.html:

window.onload = function() {
  document.getElementById('preloader').style.display = 'none';
};

While this solution works for the initial load, I am facing issues when it comes to showing and hiding the preloader on page changes.

To show the preloader again after a page change, I attempted adding this logic to the beforeDestroy() hook of my Layout component:

beforeDestroy() {
  this.preloader.style.display = 'block';
}

This successfully displays the preloader upon route changes. However, if I try to include hiding logic in the mounted() method like so:

mounted() {
  this.preloader.style.display = 'none';
}

The preloader never appears in the first place. I've searched for resources on loading indicators specific to SPAs, but have only found examples related to async calls using axios or fetch. While I have experience creating preloaders in static HTML files, navigating this within SPAs is proving challenging. Can someone provide guidance or suggest keywords for further research? Any help would be appreciated.

Answer №1

If you are facing this scenario, Vuex can be a helpful solution.

Start by defining your state in src/main.js

import DefaultLayout from "~/layouts/Default.vue";
import Vuex from "vuex";

export default function(Vue, { appOptions }) {
  Vue.component("Layout", DefaultLayout);
  Vue.use(Vuex);

  appOptions.store = new Vuex.Store({
    state: {
      loading: false,
    },
    mutations: {
      on(state) {
        state.loading = true;
      },
      off(state) {
        state.loading = false;
      },
    },
  });
}

Next, integrate a spinner into ./src/layouts/Default.vue

<template>
  <div class="layout">
    // Implement your spinner here or use another method
    <div v-if="$store.state.loading">loading</div>
    <slot />
  </div>
</template>

Lastly, include code to commit pages, templates, or components as shown below

<script>
export default {
  created() {
    // Initially commit "on"
    this.$store.commit("on");

    // Commit "off" at the end, after data fetching or any other actions.
    this.$store.commit("off");
  },
};
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error encountered in Vue code, lacks default export on Editor Terminal

I'm not experiencing any issues in the browser, I am getting the desired output. However, why does this keep showing up in the editor terminal? Any assistance would be greatly appreciated. Error - No Default Export: The module "/vue3/src/components/ ...

How can I retrieve and dismiss vee-validate errors from within a Vue component without direct access to the Vue instance?

I am having trouble clearing errors after closing a modal or sending data to the database outside of the Vue instance. I have tried using vm.$validator.errors.clean() and reset but they are not working for me. Do you have any suggestions on how to access t ...

What is the best way to reduce the width of the preformatted tag?

Is there a way to adjust the width of the pre tag in order to avoid affecting the q-card when resizing the browser window? I am trying to create a q-card that can display code similar to what you see in ChatGPT. However, the q-card's size is not respo ...

Issue with Vue component's computed property not responding as expected

I am currently working on two components: OperatorsList and OperatorButton. The OperatorsList consists of buttons, and when I click on a button, I want to update some data: I emit select with the operator.id This event is captured by the OperatorList c ...

Error in Quasar application: essential modules were not installed properly via npm

After creating a quasar app using quasar create and confirming it worked with quasar dev, I decided to upload the code to GitHub for collaboration. I created a repository and uploaded everything except for node_modules and package-lock.json. Next, I delet ...

What are the distinct roles of the server and client in a Nuxt SSR application?

Currently, I am working with Nuxt 2.13 and developing an e-commerce platform. However, I have encountered some server resource issues where the initial site load is taking longer than expected (although route changes are fast and smooth). I am curious to ...

Inert child component in Vue

Within an application utilizing a Vuex store, there exists a getter named getQueryParams. This getter retrieves an object that contains the parameters being sent to a database query. If any parameters are present (indicating that the user has performed a q ...

Concealing Vue object properties

Is it feasible to indicate specific object properties that should not be displayed? This can come in handy for debugging purposes, especially when dealing with large objects or objects that create a loop. For instance, let's say we have an object: c ...

Axios consistently produces results in the form of strings but always seem to omit the final

I'm encountering an issue with my axios post method. public function viewAuthCheck(Request$request){ return [ 'test' => 'hello!' ]; } Here is my axios function: axios.post('/timetracking/settings/auth/check ...

Exploring VueJS: Extracting nested object values from the Vuex store

I'm encountering an issue accessing a nested property of the store state data that returns as undefined when I attempt to access it. Here is the data I am working with: const state = { entity: { initial: {valid: false}, general: {valid: fals ...

The method options.domAPI is not a valid function in this context

While attempting to customize global variables using stylus config in Vuetify, I discovered that it is no longer supported. To address this issue, I executed the following command to install the necessary loaders: npm i --save-dev stylus stylus-loader css ...

Steps for resetting the Vue 3 scaffolding

Two options to scaffold a new Vue project are npm init vue@latest and npm create vue@3. I recall there is a specific command that allows you to re-initialize the scaffolding process in order to add additional features like TypeScript or Cypress. Unfortuna ...

Changing the URL within a Vue.js component without navigating away from the component

Just starting out with VueJs and working with wizaplace. I currently have a route set up as /breweries/:id, which uses the company's ID to fetch information from the wizaplace API. Within this data, there is a slug that I would like to display in the ...

Error: Unable to access the 'push' property of an undefined element while utilizing Vue router along with Vue 3

Hello everyone, I've encountered an issue with Vue 3 and Vite. I'm attempting to utilize the router but am facing difficulties as it cannot be found. props: ["usuario", "senha"], setup(props) { const errorMessage = ...

Adding data to an array using V-Bind in VueJS

I am currently working on a project that involves retrieving data from multiple devices and displaying the data on a chart in real-time. The goal is to update the chart every second as new data comes in. Below is the code snippet I have been using: index ...

Tips to modify the parent CSS in a scoped style?

i am looking for a way to modify the CSS class of a parent element from a child component, and then reset it when moving away. How can I achieve this? Parent Component: <template> <p id="parent" class="parent-text-color"> ...

Creating Vue methods functions in separate JavaScript files

Hi there, I'm new to this so please forgive me if my question seems silly. I have a vue component called vuu /path_to_main/vue_file/app.js const vuu = new Vue({ el: '#vuu', data: { latitude: 'longi', long ...

Prevent unnecessary clicks with Vue.js

In my vue.js application, there is a feature to remove items. The following code snippet shows the div element: <div class="ride-delete" @click="delete"> <p>Delete</p> </div> This is the function used to handle the click ...

Alter the dimensions and material displayed on Vue

In my Vue.js project, I have a topbar with two divs whose size and content need to be adjusted based on whether the user is logged in. If they are not logged in, it should look like this: <div id='search' width="400px"></div><div ...

Is it possible to use Vuelidate for password validation in Vue.js?

I found a helpful reference on How to validate password with Vuelidate? validations: { user: { password: { required, containsUppercase: function(value) { return /[A-Z]/.test(value) }, containsLowercase: fu ...