To enhance user experience, I recommend utilizing a loader with its own vuex state.
- Having its own vuex state allows for easy control from any component.
- Simple function calls can be used to interact with the loader.
- Avoiding the use of props and events comes naturally.
Firstly, identify where the loader will be required:
- Will it be used for all API calls?
- Is it intended for tasks that are resource-intensive in the browser (e.g., processing a large file)?
- Or perhaps it should only appear in specific scenarios (such as when a user attempts to log in).
If the loader is not closely tied to a specific component (as in scenario 1), it would be more logical to include it in your main Vue file (e.g., App.vue if you're using vue-cli).
For example:
<template>
<div id="app">
<loader></loader>
<router-view></router-view>
</div>
</template>
<script>
import Loader from './components/shared/loader/Loader'
export default {
name: 'app',
components: {
Loader
}
}
</script>
This approach eliminates the need to include loader.vue in every other component file.
Before proceeding, let's examine the loader component and store being utilized.
<template>
<div class='loader-container' :class='{"show": show, "hidden": !show}'>
<div class="curved-div">
<div class="colour-magic">
<i class='fa fa-circle-o-notch rotate'></i>
</div>
<div class="loading">
{{ loading }}
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import * as NameSpace from '../../../store/NameSpace'
export default {
data () {
return {
loading: 'Loading...'
}
},
computed: {
...mapGetters({
show: NameSpace.GET_LOADER_STATE
})
}
}
</script>
<style scoped>
.loader-container {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
}
.curved-div {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%);
border-radius: .3rem;
width: 20rem;
padding:1rem;
background: white;
box-shadow: 0 0 .1rem #fefefe;
}
// CSS styling continues...
Please note the utilization of font-awesome for the loader graphic.
Furthermore, here is the relevant store section:</p>
<pre><code>import * as NameSpace from '../NameSpace'
const state = {
[NameSpace.LOADER_STATE]: false
}
// Store getters, mutations, and actions follow...
A usage example incorporating the store mutation function for managing the loader during an API call:
// This JavaScript file demonstrates how to interact with the store for loader management
login (username, password) {
loaderSwitch(true)
return new Promise((resolve, reject) => {
SomeEndpoint.logIn(username, password, {
success (user) {
loaderSwitch(false)
resolve(user.attributes)
},
error (user, error) {
loaderSwitch(false)
reject(errorHelper(error.code))
}
})
})
// Remaining logic...
By adopting this method, the loader component remains independent of individual components where login functionality may be implemented.