当前位置:首页 > VUE

vue axios实现loading

2026-02-19 06:54:49VUE

使用 Axios 拦截器实现全局 Loading

在 Vue 项目中,可以通过 Axios 的请求拦截器和响应拦截器实现全局 Loading 效果。以下是一个完整的实现方案:

安装 Axios(如果未安装):

npm install axios

在 Vue 项目中创建 Axios 实例并配置拦截器:

vue axios实现loading

// 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:

vue 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 隐藏
}

标签: vueaxios
分享给朋友:

相关文章

拖拽式编程vue实现

拖拽式编程vue实现

拖拽式编程在 Vue 中的实现方法 使用 HTML5 原生拖放 API Vue 可以结合 HTML5 的拖放 API 实现基础拖拽功能。通过 draggable 属性标记可拖拽元素,监听 dragst…

vue实现冰墩墩

vue实现冰墩墩

使用 Vue 实现冰墩墩动画 通过 Vue 的动画特性和 SVG 技术,可以动态渲染冰墩墩的形象。以下是具体实现方法: 准备 SVG 素材 冰墩墩的形象通常由多个 SVG 路径组成,包括身体轮廓…

vue实现钟表

vue实现钟表

使用 Vue 实现动态钟表 以下是一个基于 Vue 3 的动态钟表实现方案,包含时分秒指针和数字时间显示。 模板部分 <template> <div class="clock-…

vue实现tablegrid

vue实现tablegrid

Vue 实现 TableGrid 的方法 使用 Element UI 的 Table 组件 Element UI 提供了强大的 Table 组件,可以快速实现表格布局。安装 Element UI 后,…

vue实现$.extend

vue实现$.extend

Vue 实现类似 jQuery 的 $.extend 功能 在 Vue 中实现类似 jQuery 的 $.extend 功能,可以通过多种方式完成。$.extend 主要用于合并多个对象的属性,Vue…

vue grid实现

vue grid实现

Vue Grid 实现方法 在 Vue 中实现网格布局可以通过多种方式完成,包括使用原生 CSS Grid、第三方组件库或自定义组件。以下是几种常见方法: 使用原生 CSS Grid 通过 Vue…