vue-请求-全局loading-elementUI

请求—全局loading—避免操作快导致的误操作------使用请求、响应拦截器
合并loading,一个请求触发一次loading,避免loading一直闪烁抖动的问题------使用lodash中的debounce

核心:showFullScreenLoading , tryHideFullScreenLoading
/ src / utils / request.js

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import {
  showFullScreenLoading,
  tryHideFullScreenLoading,
} from './loading'
// create an axios instance
const service = axios.create({
  timeout: 15000, // 请求超时时间
  useMock: false
})

// request拦截器
service.interceptors.request.use(
  config => {
    showFullScreenLoading()
    if (store.getters.useMock) {
      config.baseURL =
        '......'
    }
    // Do something before request is sent
    if (store.getters.token) {
      config.headers.Authorization = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
    } else {
      config.headers.Authorization = '......'
    }
    return config
  },
  error => {
    // Do something with request error
    // console.log(error) // for debug
    tryHideFullScreenLoading()
    Promise.reject(error)
  }
)

// respone拦截器
service.interceptors.response.use(
  response => {
    tryHideFullScreenLoading()
    /**
     * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
     * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
     */
    const res = response.data
    if (response.status === 401 || res.status === 40101) {
      MessageBox.confirm(
        '你已被登出,可以取消继续留在该页面,或者重新登录',
        '确定登出',
        {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        store.dispatch('LogOut').then(() => {
          location.reload() // 为了重新实例化vue-router对象 避免bug
        })
      })
      tryHideFullScreenLoading()
      return Promise.reject('error')
    }
    ......
  },
  error => {
    tryHideFullScreenLoading()
    // 错误拦截
    const response = error.response
    if (response.status === 401 || response.data.status === 40101) {
      store.dispatch('user/LogOut').then(() => {
        location.reload() // 为了重新实例化vue-router对象 避免bug
      })
      tryHideFullScreenLoading()
      return Promise.reject('error')
    }
    ......
    if (
      response.data.message &&
      response.data.message.indexOf('ORA-12899') != -1
    ) {
      Message({
        message: '输入字符长度过长,请重新输入',
        type: 'error'
      })
      tryHideFullScreenLoading()
      return Promise.reject(error)
    }
    ......
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    tryHideFullScreenLoading()
    return Promise.reject(error)
  }
)
export default service

样式:loading.js

import { Loading } from 'element-ui'
import _ from 'lodash'

let needLoadingRequestCount = 0
let loading

function startLoading() {
  loading = Loading.service({
    lock: true,
    text: '加载中,请稍等……',
    background: 'rgba(0, 0, 0, 0.05)'
  })
}

function endLoading() {
  loading.close()
}

const tryCloseLoading = () => {
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

export function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}

export function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
  // 创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 func 方法
    _.debounce(tryCloseLoading, 300)()
  }
}

你可能感兴趣的:(vue)