可用性的緣故,我會建議使用具有裝載機其自己的vuex狀態。
- 這將允許您從任何組件控制它。
- 您可以通過簡單的函數調用輕鬆使用它。
- 自然避免道具和事件。
首先定義,你需要這種特殊的裝載機:
- 是它被用於所有的API調用?
- 一些瀏覽器密集型任務(如處理加載的文件)。
- 或者在本質上更具體的東西(也許只顯示當用戶試圖登錄裝載機)
如果加載程序不嚴格的情況下,1連接到任何組件像然後會更有SENS繼續在主VUE文件的加載器(如果您正在使用VUE-CLI然後App.vue)
事情是這樣:
<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>
有了這個,你不必添加loader.vue在每個其他組件文件中。但首先,我將向您展示我正在使用的加載程序組件和商店。
<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;
}
.curved-div > * {
display: inline-block;
}
.rotate {
border-radius: 50%;
padding: .5rem;
animation-name: rotate;
animation-duration: .7s;
animation-iteration-count: infinite;
animation-delay: 0s;
}
.loading {
text-align: center;
width: 12rem;
font-size: 1.8rem;
}
.show {
visibility: visible;
opacity: 1;
z-index: 1;
transition: opacity 0.5s ease-out, visibility 0.5s ease-out, z-index 0.5s ease-out;
}
.hidden {
opacity: 0;
visibility: hidden;
z-index: 0;
transition: opacity 0.5s ease-out, visibility 0.5s ease-out, z-index 0.5s ease-out;
}
@keyframes rotate {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(360deg);
}
}
.colour-magic {
animation-name: colorMagic;
animation-duration: 20s;
animation-iteration-count: infinite;
animation-delay: 0s;
}
@keyframes colorMagic {
0% { color: rgb(179,10,10); }
10% { color: rgb(227,132,22); }
20% { color: rgb(164,153,7); }
30% { color: rgb(26,171,19); }
40% { color: rgb(19,144,177); }
50% { color: rgb(14,16,221); }
60% { color: rgb(27,9,98); }
70% { color: rgb(58,11,111); }
80% { color: rgb(126,14,129); }
90% { color: rgb(208,19,121); }
100% { color: rgb(198,18,18); }
}
</style>
請注意,我正在使用font-awesome來裝載程序。
和這裏是商店:
import * as NameSpace from '../NameSpace'
// you can also use the namespace: true in your store and eliminate the need of NameSpace.js
const state = {
[NameSpace.LOADER_STATE]: false
}
const getters = {
[NameSpace.GET_LOADER_STATE]: state => {
return state[NameSpace.LOADER_STATE]
}
}
const mutations = {
[NameSpace.MUTATE_LOADER_STATE]: (state, payload) => {
state[NameSpace.LOADER_STATE] = payload
}
}
const actions = {
[NameSpace.LOADER_SHOW_ACTION]: ({ commit }, payload) => {
commit(NameSpace.MUTATE_LOADER_STATE, payload)
}
}
export default {
state,
getters,
mutations,
actions
}
甲使用例如:
// This is not a .vue file it is a .js file, therefore a different way of using the store.
import Vue from 'vue'
import * as NameSpace from 'src/store/NameSpace'
import loaderState from 'src/store/modules/loader'
/**
* Pass the mutation function to reduce the text length
* This function can now be used in the api calls to start/stop the loader
* as the api starts and finishes.
*/
let loaderSwitch = loaderState.mutations[NameSpace.MUTATE_LOADER_STATE].bind(null, loaderState.state)
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))
}
})
})
現在,不論在使用登錄的組分,所述加載器組件不需要有保持。