Vue全局loading实现
Vue 全局 Loading 的实现方法
通过 Vue 指令实现
创建一个自定义指令,用于在元素上显示或隐藏 loading 状态。在指令的钩子函数中,动态添加或移除 loading 元素。
// main.js
import Vue from 'vue'
Vue.directive('loading', {
bind(el, binding) {
const loadingDiv = document.createElement('div')
loadingDiv.className = 'loading-mask'
loadingDiv.innerHTML = '<div class="loading-spinner"></div>'
el.loadingElement = loadingDiv
if (binding.value) {
el.appendChild(loadingDiv)
}
},
update(el, binding) {
if (binding.value) {
el.appendChild(el.loadingElement)
} else {
el.removeChild(el.loadingElement)
}
}
})
// App.vue
<template>
<div v-loading="isLoading"></div>
</template>
使用 Vue 插件封装
将 loading 功能封装为 Vue 插件,通过全局方法调用显示和隐藏 loading。
// loading.js
const Loading = {
install(Vue) {
Vue.prototype.$loading = {
show() {
// 显示 loading 逻辑
},
hide() {
// 隐藏 loading 逻辑
}
}
}
}
// main.js
import Loading from './loading'
Vue.use(Loading)
// 组件中使用
this.$loading.show()
this.$loading.hide()
结合 Vuex 状态管理
使用 Vuex 管理全局 loading 状态,在需要的地方通过 mutations 改变状态。
// store.js
const store = new Vuex.Store({
state: {
loading: false
},
mutations: {
setLoading(state, payload) {
state.loading = payload
}
}
})
// 组件中使用
this.$store.commit('setLoading', true)
this.$store.commit('setLoading', false)
第三方库实现
使用现成的第三方库如 element-ui 的 loading 组件或 vue-loading-overlay。
// 使用 element-ui
import { Loading } from 'element-ui'
let loadingInstance = Loading.service(options)
loadingInstance.close()
// 使用 vue-loading-overlay
import Loading from 'vue-loading-overlay'
import 'vue-loading-overlay/dist/vue-loading.css'
Vue.use(Loading)
样式和动画
为 loading 添加样式和动画效果,提升用户体验。
.loading-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
请求拦截器集成
在 axios 拦截器中自动显示和隐藏 loading,减少手动调用的代码量。

// http.js
import axios from 'axios'
let loadingCount = 0
axios.interceptors.request.use(config => {
loadingCount++
showLoading()
return config
})
axios.interceptors.response.use(response => {
loadingCount--
if (loadingCount === 0) {
hideLoading()
}
return response
}, error => {
loadingCount--
if (loadingCount === 0) {
hideLoading()
}
return Promise.reject(error)
})






