axios请求封装 loading多次闪烁

request.js

import { nextTick } from 'vue'
import axios from 'axios'
import { ElNotification,ElLoading  } from 'element-plus'
import store from '../store/index'
import _ from 'lodash'
import { getToken, rmToken } from '@/utils/store.js'
let loadingInstance //loading 实例
let needLoadingRequestCount = 0 //当前正在请求的数量


const codeMessage = {
  400: '请求错误',
  401: '登录状态失效,请重新登录',
  403: '拒绝访问',
  404: '请求地址不存在',
  500: '服务器错误,请稍后再试',
  502: '网关错误',
  503: '服务不可用,服务器暂时过载或维护',
  504: '网关超时',
}

const request = axios.create({
  baseURL: process.env.VUE_APP_API_HOST,
  timeout: 20000,
})

request.interceptors.request.use(config => {
  showLoading()
  store.getters.token &&
      (config.headers['Authorization'] = store.getters.token)
    store.getters.tenantId &&
      (config.headers['tenant_id'] = store.getters.tenantId)
    return config
},error =>{
  closeLoading() 
  ElNotification.error({
    title: '错误',
    message: '请求超时!',
  })
  Promise.reject(error)
})  


// response拦截器
request.interceptors.response.use(
  response => {
    closeLoading()
    // 可以通过返回的code标示请求状态,如通过 XMLHttpRequest状态码标示,逻辑可写在error中
    let { status } = response
    if (status === 200) {
      return response
    } else {
      Notification.error({
        title: '错误',
        message: '请求StatusCode !== 200',
      })
      return Promise.reject(response)
    }
  },
  error => {
    closeLoading()
    if (error.response) {
      // 发出了请求,服务器返回的状态码不在2xx范围内
      errorShowMsg(error.response.status)
    } else if (error.request) {
      // 已发出请求,但是未收到回复
      // error.request 在浏览器环境是 XMLHttpRequest 的实例
      console.log(error.request)
      ElNotification.error({
        title: '错误',
        message: '服务错误',
      })
    } else {
      ElNotification.error({
        title: '错误',
        message: '服务错误',
      })
    }
    return Promise.reject(error)
  }
)


function errorShowMsg(code) {
  if (code === 401) {
    if (getToken()) {
      ElNotification.error({
        title: '错误',
        message: codeMessage[code],
        duration: 2000,
      })
    }
    rmToken()
  } else {
    ElNotification.error({
      title: '错误',
      message: codeMessage[code],
    })
  }
}

// 全局loading 函数
function showLoading() {
  if (needLoadingRequestCount === 0 && !loadingInstance) {
    loadingInstance = ElLoading.service({
      target: 'body',
      lock: true,
      text: '正在加载...',
      background: 'rgba(0,0,0,0.3)',
    })
  }
  needLoadingRequestCount++
}

function closeLoading() {
  nextTick(() => {
    // 以服务的方式调用的 Loading 需要异步关闭
    needLoadingRequestCount--
    needLoadingRequestCount = Math.max(needLoadingRequestCount, 0) // 保证大于等于0
    if (needLoadingRequestCount === 0) {
      if (loadingInstance) {
        hideLoading()
      }
    }
  })
}

//防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
//因为有时会碰到在一次请求完毕后又立刻又发起一个新的请求的情况(比如删除一个表格一行后立刻进行刷新)
//这种情况会造成连续 loading 两次,并且中间有一次极短的闪烁。通过防抖可以让 300ms 间隔内的 loading 便合并为一次,避免闪烁的情况。
var hideLoading = _.debounce(() => {
  loadingInstance.close()
  loadingInstance = null
}, 300)

export default request

api.js
import request from '@/utils/request.js'
// 获取所有信息接入抓取内容展示
export function getSourceResList(page, data = {}) {
  return request({
    url: `/radioem/m/sourceRes/pageList/${page.pageNum}/${page.pageSize}`,
    method: 'post',
    data
  })
}

存储数据
/**
 * 存储数据
 */

 const KEY_ITEM = 'tagsView'
 export const setItem = (KEY_ITEM, value) => {
  // 将数组、对象类型的数据转化为 JSON 字符串进行存储
  if (typeof value === 'object') {
    value = JSON.stringify(value)
  }
  window.localStorage.setItem(KEY_ITEM, value)
}

/**
 * 获取数据
 */
export const getItem = KEY_ITEM => {
  const data = window.localStorage.getItem(KEY_ITEM)
  try {
    return JSON.parse(data)
  } catch (err) {
    return data
  }
}

/**
 * 删除数据
 */
export const removeItem = KEY_ITEM => {
  window.localStorage.removeItem(KEY_ITEM)
}

/**
 * 删除所有数据
 */
export const removeAllItem = KEY_ITEM => {
  window.localStorage.clear()
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值