vue3+ts+vite axios的封装,axios 声明合并扩展AxiosRequestConfig额外参数 第五回

// 安装axios 
npm install axios  和第三方js-cookie、qs 。懂的都懂。

  由于很多业务复杂,后端被拆分成多个微服务,所以axios必须来一层简单的封装。下面贴出整个request.ts 脚本
在types目录下,新建axios.d.ts ,内容如下

import { AxiosRequestConfig } from 'axios'

declare module 'axios' {
  export interface AxiosRequestConfig {
    /** 服务名 */
    serv?: string
    /** api版本 */
    apiVersion?: string
    /** 是否需要loading */
    needLoading?: boolean
  }
} 

  

import { ElLoading } from 'element-plus'
import axios from 'axios'
import qs from 'qs'
import Cookies from 'js-cookie'

// 定义一个常见后端请求返回
type BaseApiResponse = {
  code: number
  message: string
  data: any
  status: boolean
}

const request = axios.create({
  baseURL: 'http://xxx',
  timeout: 300000, // 请求超时时间
  paramsSerializer: params => {
    return qs.stringify(params, { indices: false })
  }
})

// 这里需要注意,按需引入的时候,需要在main.ts引入样式 import 'vue-simple-uploader/dist/style.css'
const defaultElLoadingOptions = {
  lock: true,
  text: '请稍后',
  body: true,
  background: 'rgba(0, 0, 0, 0.1)'
}

let loadingInstance: any = null

/**
 * interceptor request
* AxiosRequestConfig额外扩展的serv(微服务名),apiVersion */ request.interceptors.request.use((config) => { if (config.serv) { config.baseURL += `${config.serv}/${config.apiVersion}` } const token = Cookies.get('login_ticket') config.headers['Authorization'] = decodeURIComponent(token); if (config.method === 'get' || config.method === 'GET') { config.params = config.data } if (config.needLoading) { loadingInstance = ElLoading.service(defaultElLoadingOptions) setTimeout(() => { loadingInstance.close() }, 30000) } return config }, error => { Promise.reject(error) loadingInstance.close() } ) // 不需要登录的白名单 const needLogin = (hash: string) => { let path = /login|register\/public/ const witePaths = [ '#/',
'#/public' '#/login' ]; return ( witePaths.indexOf(hash.split('?')[0]) === -1 && hash.search(path) === -1 ); } // interceptor response request.interceptors.response.use( async response => { if (response.headers && response.headers.authorization) { Cookies.set('token', response.headers.authorization) } const dataAxios = response.data if (loadingInstance) { loadingInstance.close() } if (dataAxios && dataAxios.httpCode - 0 === 401 && needLogin(location.hash)) { localStorage.setItem('source', encodeURIComponent(location.href)) location.href = `/#/login` return } // 这个状态码是和后端约定的 // const { status } = response let status = null if (dataAxios.status && !isNaN(dataAxios.status - 0)) { status = dataAxios.status } if (dataAxios.code && !isNaN(dataAxios.code - 0)) { status = dataAxios.code } // 根据 code 进行判断 if (status !== null) { // 有 code 代表这是一个后端接口 可以进行进一步的判断 switch (status) { case 0: return dataAxios.result || dataAxios.result == 0 ? dataAxios.result : dataAxios case 200: return dataAxios.result || dataAxios.result == 0 ? dataAxios.result : dataAxios case 401: if (needLogin(location.hash)) { // 处理token置换,或者登陆跳转, } return case 'xxx': // [ 示例 ] 其它和后台约定的 code break default: // 不是正确的 code // errorCreate(`${dataAxios.message}`) break } } else { // 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本 return dataAxios } }, error => { if (loadingInstance) { loadingInstance.close() } if (error && error.response) { if (error.response.data && error.response.data.message && error.response.data.message == '无访问权限') { location.href = '/home' return } switch (error.response.status) { case 400: error.message = `请求错误: ${error.response.data && error.response.data.message}`; break case 401: error.message = '未授权,请登录'; Cookies.set('login_ticket', ''); Cookies.set('refresh_token', ''); location.href = `/#/login?source=${encodeURIComponent(location.href)}`; break case 403: error.message = '拒绝访问'; break case 404: error.message = `请求地址出错: ${error.response.config.url}`; break case 408: error.message = '请求超时'; break case 500: error.message = '服务器内部错误'; break case 501: error.message = '服务未实现'; break case 502: error.message = '网关错误'; break case 503: error.message = '服务不可用'; break case 504: error.message = '网关超时'; break case 505: error.message = 'HTTP版本不受支持'; break default: break } } // errorLog(error) return Promise.reject(error) } ) export default request

  至此,axios的封装告一段落。调用的部分如下。

import request from '@/utils/request'

// // 验证码
export function getVerificationCode() {
  return request({
    method: 'get',
    url: '/verification/code',
    serv: '/auth',
    apiVersion: 'v1',
    needLoading: true
  }
  )
}

  

posted @ 2023-06-05 14:07  大楚打码人  阅读(443)  评论(0编辑  收藏  举报