[Vuejs]-Vue.js : Add loading bar to whole page when request is in progress

0👍

Your best bet is going to probably be to put in an overlay, which can be placed at the very bottom of your root element.

As a rough example:

         <v-col cols="3">
          <v-btn
            v-if="editGroup"
            light
            class="mx-2"
            @click="editGroup = false"
          >
            <v-icon left>mdi-close</v-icon>
            Close
          </v-btn>
          <v-btn
            v-if="editGroup" 
            light 
            class="mx-2" 
            @click="clickSave"
            >
            <v-icon left>mdi-content-save</v-icon>
            Save
          </v-btn>
          <v-btn
            v-if="
              canShowButton(['administrateur', 'configurateur']) &&
              !editGroup
            "
            light
            class="mx-2"
            @click="editGroup = true"
          >
            <v-icon left>mdi-pencil</v-icon>
            Edit
          </v-btn>
          <--The overlay will not display when loading is false-->
          <v-overlay v-model="loading">
            <v-progress-circular
            indeterminate
            color="primary">
            </v-progress-circular> 
          </v-overlay>
        </v-col>

The overlay will cover the entire screen until the loading prop is marked as false

https://vuetifyjs.com/en/components/overlays/

Edit:

Additionally, loading will have to be set in the data section of your page when you first load in.

<script>
  export default {
    data: () => ({
      loading: false,
    }),
    },
  }
</script>

0👍

This is what state management such as pinia is for. If you set up a pinia store like so:

import { defineStore } from "pinia"

export enum PageState {
  LOADING,
  LOADED,
  ERROR
}

export const usePageStore = defineStore({
  state: () => ({
    pageState: PageState.LOADED
  }),
  getters: {},
  actions: {
    saveData(endpointPrefix, groupId, newData) {
      try {
        // Put all your URL building/data calling work here
      } catch (e) {
        throw new Error(e)
      }
    },
  },
})

Then, instead of doing all the data work in your vue script, you just do this part:

pageStore = usePageStore()

async clickSave() {
  try {
    pageStore.pageState = PageState.LOADING
    const response = await pageStore.getData(this.endpointPrefix, this.groupId, dat)
    this.$nuxt.$emit('show-notification', {
          text: 'updated',
          color: 'green',
        })
    this.loadData(this.groupid)
    pageStore.pageState = PageState.LOADED
  } catch (e) {
    pageStore.pageState = PageState.ERROR
     this.$nuxt.$emit('show-notification', {
        text:
          'could not be updated !' +
          error.response.data,
        color: 'red',
      })
  }  
}

Then your main, overarching page view can access the same store, watch that variable, and change according to show whatever you need.

Leave a comment