DEV Community

loading...
Cover image for Adding VueJS Loading State Indicators (Promises)
Promatia

Adding VueJS Loading State Indicators (Promises)

albertmarashi profile image AlbertMarashi Updated on ・2 min read

Add Loading State Indicators to VueJS

Read full post here

While trying to figure out a good way to manage loading state for Promatia's sign up form and other asynchronous pages & components. I stumbled upon a neat way of managing asynchronous loading state.

Web apps often require loading state (things like loading spinners) to let a user know that an operation is taking place. These operations often take time, so it's best to let the user know something is loading, which helps improve UX and prevents form resubmissions and etc.

I created a neat module that can help with managing asynchronous loading state (promises) in a VueJS app

import { ref, computed } from '@vue/composition-api' // using vue 3 syntax

export default function () {
    let loading = ref(false) //initial value of false

    return computed({
        get () {
            return loading.value // return the loading value
        },
        async set (value) {
            loading.value = true //update loading ref value to be true
            await value //wait for promise completion
            loading.value = false //update loading ref back to false
        }
    })
}

The way it's used:

<button @click="promise = asyncFunction()">Click<button/>
<overlayLoader v-if="promise"/>
import promiser from '@/utils/promiser' //the helper we've just created 

export default {
    setup(){
        return {
            promise: promiser() //create and expose an instance of the computed variable
        }
    }
}

<overlayLoader/> is a component which displays a sync loader animation on top of a form, which captures clicks and prevents further actions

When <button> is clicked, it triggers the set() function inside the computed variable, which updates the loading state.

Alt Text
After clicking
Alt Text

Discussion

pic
Editor guide
Collapse
rolandcsibrei profile image
Roland Csibrei

Thanks for the article. If you have a global loader, I think, the VUE global event bus should do a cleaner job. If Vuex is used in the project, it can be used to hold the loading status globally.

Collapse
albertmarashi profile image
AlbertMarashi Author

Actually I prefer having it separated, different components can be doing different operations at the same time, and each one could have it's own loading state.

Eg: a dashboard is loading with each grid item loading it's own data