vue axios实现loading
使用 Axios 拦截器实现全局 Loading
在 Vue 项目中,可以通过 Axios 的请求拦截器和响应拦截器实现全局 Loading 效果。以下是一个完整的实现方案:
安装 Axios(如果未安装):
npm install axios
在 Vue 项目中创建 Axios 实例并配置拦截器:

// src/utils/request.js
import axios from 'axios'
import { ElLoading } from 'element-plus' // 以 Element Plus 为例
const service = axios.create({
baseURL: '/api',
timeout: 5000
})
let loadingInstance
service.interceptors.request.use(config => {
loadingInstance = ElLoading.service({
lock: true,
text: '加载中...',
background: 'rgba(0, 0, 0, 0.7)'
})
return config
}, error => {
loadingInstance.close()
return Promise.reject(error)
})
service.interceptors.response.use(response => {
loadingInstance.close()
return response.data
}, error => {
loadingInstance.close()
return Promise.reject(error)
})
export default service
在组件中使用封装好的 Axios 实例
import request from '@/utils/request'
export default {
methods: {
fetchData() {
request.get('/user/list')
.then(data => {
console.log(data)
})
.catch(error => {
console.error(error)
})
}
}
}
自定义 Loading 组件实现
如果需要使用自定义 Loading 组件而非 UI 库的 Loading:
// src/components/CustomLoading.vue
<template>
<div v-if="visible" class="loading-overlay">
<div class="loading-spinner"></div>
<div class="loading-text">{{ text }}</div>
</div>
</template>
<script>
export default {
props: {
visible: Boolean,
text: {
type: String,
default: 'Loading...'
}
}
}
</script>
<style>
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
}
</style>
在 Axios 拦截器中使用自定义 Loading:

import Vue from 'vue'
let loadingCount = 0
let loadingComponent
function showLoading() {
if (loadingCount === 0) {
const LoadingConstructor = Vue.extend(CustomLoading)
loadingComponent = new LoadingConstructor({
propsData: { visible: true }
})
loadingComponent.$mount()
document.body.appendChild(loadingComponent.$el)
}
loadingCount++
}
function hideLoading() {
loadingCount--
if (loadingCount <= 0) {
loadingComponent.$el.remove()
loadingComponent.$destroy()
loadingComponent = null
loadingCount = 0
}
}
service.interceptors.request.use(config => {
showLoading()
return config
})
service.interceptors.response.use(response => {
hideLoading()
return response
}, error => {
hideLoading()
return Promise.reject(error)
})
按需启用 Loading 的功能
某些请求可能需要禁用 Loading,可以通过自定义配置实现:
service.interceptors.request.use(config => {
if (config.showLoading !== false) {
showLoading()
}
return config
})
// 使用时不显示 Loading
request.get('/user/info', { showLoading: false })
防止快速请求导致的 Loading 闪烁
添加延时隐藏逻辑,避免 Loading 频繁闪烁:
let hideLoadingTimer
function hideLoading() {
hideLoadingTimer = setTimeout(() => {
if (loadingCount <= 0 && loadingComponent) {
clearTimeout(hideLoadingTimer)
loadingComponent.$el.remove()
loadingComponent.$destroy()
loadingComponent = null
}
}, 300) // 延迟 300ms 隐藏
}






