Multiple Process Loader Management for Vue and Vuex
vuex-loading
Multiple Process Loader Management for Vue and Vuex.
vuex-loading helps to manage multiple loading states on the page without any conflict. It's based on a very simple idea that manages a Vuex store with multiple loading states. The built-in loader component listens its registered loader and immediately become loading state.
Installation
$ npm install vuex-loading
# or if you using Yarn
$ yarn add vuex-loading
Usage
import { createVuexLoader } from 'vuex-loading'
const VuexLoading = createVuexLoader({
// The Vuex module name, 'loading' by default.
moduleName: 'loading',
// The Vue component name, 'v-loading' by default.
componentName: 'v-loading',
// Vue component class name, 'v-loading' by default.
className: 'v-loading',
});
Vue.use(Vuex)
Vue.use(VuexLoading)
const store = new Vuex.Store({
plugins: [VuexLoading.Store],
});
Then you should register loading module:
new Vue({
el: '#app',
store,
computed: {
...mapGetters('loading', [
/*
`isLoading` returns a function with a parameter of loader name.
e.g. `isLoading('creating user')` will return you a boolean value.
*/
'isLoading',
/*
`anyLoading` returns a boolean value if any loader name exists on store.
*/
'anyLoading',
])
},
methods: {
startLoading() {
/*
VuexLoading registers $startLoading method with loader name.
When you start a loader, it pushes the loader name to loading state.
*/
this.$startLoading('fetching data');
},
endLoading() {
/*
VuexLoading registers $startLoading method with loader name.
When you stop a loader, it pulls the loader name from loading state.
*/
this.$endLoading('fetching data');
},
},
});
Global Template Helpers
vuex-loading provides some helpers to you to use in your templates.
$anyLoading
Returns boolean value if any loader exists in page.
<template>
<progress-bar v-if="$anyLoading">Please wait...</progress-bar>
</template>
$isLoading(loader String)
Returns boolean value if given loader exists in page.
<template>
<progress-bar v-if="$isLoading('creating user')">Creating User...</progress-bar>
</template>
$startLoading(loader String)
Starts the given loader.
<template>
<button @click="$startLoading('creating user')">Create User</button>
</template>
$endLoading(loader String)
Stops the given loader.
<template>
<button @click="$endLoading('creating user')">Cancel</button>
</template>
Global Action Helpers
vuex-loading provides some helpers to you to use in your Vuex stores.
import { createActionHelpers } from 'vuex-loading'
const { startLoading, endLoading } = createActionHelpers({
moduleName: 'loader'
});
startLoading(dispatcher, loader String [,async callback])
You can trigger loader from the action. This will make your templates cleaner and you will have an accurate loader status.
startLoading
will trigger a loading and will end loader after the optional async callback is finished.
Example using the Promise returning callback function
export default {
actions: {
async createUser({ commit, dispatch }) {
const response = await startLoading(dispatch, 'creating user', () => {
return fetch("...") // Some async job that returns Promise instance.
});
commit(types.CREATE_USER, response)
}
},
// ...
}
Example call without a provided callback
export default {
actions: {
createUser({ commit, dispatch }) {
startLoading(dispatch, 'creating user');
request('/create-user', (response) => {
endLoading(dispatch, 'creating user')
commit(types.CREATE_USER, response);
});
}
},
// ...
}
endLoading(dispatcher, loader String)
Ends given loading from actions.
export default {
actions: {
async createUser({ commit, dispatch }) {
try {
const response = await startLoading(dispatch, 'creating user', () => { /* ... */ });
commit(types.CREATE_USER, response)
} catch (e) {
// In any unexpected thing occurs on runtime, end the loading.
endLoading(dispatch, 'creating user')
}
}
},
// ...
}
Using v-loading
Component
In template, you should wrap your content with v-loading
component to show loading on it.
<v-loading loader='fetching data'>
<template slot='spinner'>
This will be shown when "fetching data" loader starts.
</template>
This will be shown when "fetching data" loader ends.
</v-loading>
Better example for a button
with loading state:
<button :disabled='$isLoading("creating user")'>
<v-loading loader='creating user'>
<template slot='spinner'>Creating User...</template>
Create User
</v-loading>
</button>