vue 实现loading
实现全局Loading组件
在Vue中可以通过自定义组件结合状态管理实现全局Loading效果。以下是一种常见实现方式:
创建Loading组件

<template>
<div v-if="isLoading" class="loading-overlay">
<div class="loading-spinner"></div>
</div>
</template>
<script>
export default {
data() {
return {
isLoading: false
}
},
methods: {
show() {
this.isLoading = true
},
hide() {
this.isLoading = false
}
}
}
</script>
<style>
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #fff;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
注册为全局组件
在main.js中注册并挂载到Vue实例:
import Vue from 'vue'
import Loading from '@/components/Loading.vue'
const loading = Vue.extend(Loading)
const loadingInstance = new loading().$mount()
document.body.appendChild(loadingInstance.$el)
Vue.prototype.$loading = {
show: () => loadingInstance.show(),
hide: () => loadingInstance.hide()
}
在请求拦截器中使用
结合axios拦截器实现自动显示/隐藏:

import axios from 'axios'
axios.interceptors.request.use(config => {
Vue.prototype.$loading.show()
return config
}, error => {
Vue.prototype.$loading.hide()
return Promise.reject(error)
})
axios.interceptors.response.use(response => {
Vue.prototype.$loading.hide()
return response
}, error => {
Vue.prototype.$loading.hide()
return Promise.reject(error)
})
使用Vuex管理状态
对于大型项目,建议使用Vuex统一管理Loading状态:
// store.js
export default new Vuex.Store({
state: {
isLoading: false
},
mutations: {
SET_LOADING(state, payload) {
state.isLoading = payload
}
}
})
// 组件中使用
computed: {
isLoading() {
return this.$store.state.isLoading
}
},
methods: {
showLoading() {
this.$store.commit('SET_LOADING', true)
},
hideLoading() {
this.$store.commit('SET_LOADING', false)
}
}
按需加载的局部Loading
对于局部区域可以使用v-loading指令:
Vue.directive('loading', {
bind(el, binding) {
const loadingDiv = document.createElement('div')
loadingDiv.className = 'local-loading'
el.loadingElement = loadingDiv
if (binding.value) {
el.appendChild(loadingDiv)
}
},
update(el, binding) {
if (binding.value) {
el.appendChild(el.loadingElement)
} else {
el.removeChild(el.loadingElement)
}
}
})
.local-loading {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255,255,255,0.7);
z-index: 100;
}






