You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue项目中如何通过请求标识控制Axios拦截器加载器触发

实现带标识控制的Axios加载器拦截器

核心思路

直接在Axios请求配置中添加自定义标识(而非依赖请求头),通过拦截器识别该标识来控制加载器的显示/隐藏,同时用计数机制处理并发请求,避免单个请求结束就误关加载器。

1. 管理加载器状态

用Pinia(或Vuex、全局响应式变量)维护加载状态,这里以Pinia为例:

// stores/loader.js
import { defineStore } from 'pinia'

export const useLoaderStore = defineStore('loader', {
  state: () => ({
    isLoading: false,
    loadingCount: 0 // 并发请求计数,防止提前关闭加载器
  }),
  actions: {
    startLoading() {
      this.loadingCount++
      this.isLoading = true
    },
    stopLoading() {
      this.loadingCount--
      if (this.loadingCount <= 0) {
        this.isLoading = false
        this.loadingCount = 0 // 重置避免负数
      }
    }
  }
})

2. 配置Axios拦截器

在Axios实例中添加拦截器,识别请求配置里的showLoader标识:

// utils/axios.js
import axios from 'axios'
import { useLoaderStore } from '@/stores/loader'

const axiosInstance = axios.create({
  baseURL: '/api'
})

// 请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    if (config.showLoader) {
      const loaderStore = useLoaderStore()
      loaderStore.startLoading()
    }
    return config
  },
  error => {
    // 请求失败也要关闭对应加载器
    if (error.config?.showLoader) {
      const loaderStore = useLoaderStore()
      loaderStore.stopLoading()
    }
    return Promise.reject(error)
  }
)

// 响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    if (response.config.showLoader) {
      const loaderStore = useLoaderStore()
      loaderStore.stopLoading()
    }
    return response
  },
  error => {
    if (error.config?.showLoader) {
      const loaderStore = useLoaderStore()
      loaderStore.stopLoading()
    }
    return Promise.reject(error)
  }
)

export default axiosInstance

3. 发起请求时添加标识

需要显示加载器的请求,在配置中加入showLoader: true,轻量请求则忽略:

// 重量级请求 - 显示加载器
async fetchHeavyData() {
  try {
    const res = await axiosInstance.get('/heavy-data', {
      showLoader: true
    })
    // 处理数据
  } catch (err) {
    // 错误处理
  }
}

// 轻量请求 - 不显示加载器
async fetchLightData() {
  try {
    const res = await axiosInstance.get('/light-data')
    // 处理数据
  } catch (err) {
    // 错误处理
  }
}

4. 实现加载器组件

写一个全局加载器组件,根据状态自动显示:

<!-- components/Loader.vue -->
<template>
  <div v-if="isLoading" class="loader-overlay">
    <div class="loader-spinner"></div>
  </div>
</template>

<script setup>
import { useLoaderStore } from '@/stores/loader'
import { computed } from 'vue'

const loaderStore = useLoaderStore()
const isLoading = computed(() => loaderStore.isLoading)
</script>

<style scoped>
.loader-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.loader-spinner {
  width: 50px;
  height: 50px;
  border: 5px solid #fff;
  border-top-color: #42b983;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style>

最后在App.vue中引入该组件即可全局生效。

关于请求头失败的说明

请求头方案容易踩坑:一是非标准自定义头可能被浏览器/后端框架过滤;二是Axios在某些场景下会自动过滤非HTTP规范头。直接在请求配置中添加自定义字段是更可靠的方案,Axios会完整保留这些配置项。

内容的提问来源于stack exchange,提问作者Oraz Durdyyew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:45:34