1. Install dependencies
"dependencies": {
    "qs": "^ 6.10.1"."axios": "^ 0.21.1"
  },
Copy the code
  1. To centrally manage the configuration, create SRC /config/net.config.ts
//src/config/net.config.ts
type NetConfigSuccessCode = 200 | '200' | '000000'
// For formal projects, you can configure the interface address as required, such as "https://api.xxx.com".
// The development environment is followed by the question mark and the production environment is followed by the colon
export const baseURL: string = import.meta.env.MODE === 'development'
  ? '/xz-risk'
  : `The ${import.meta.env.VITE_RES_URL}/xz-risk`
// Set the receiving mode of back-end data application/json; Charset = utf-8 or application/x - WWW - form - urlencoded; charset=UTF-8
export const contentType: string = 'application/json; charset=UTF-8'
// Maximum request time
export const requestTimeout: number = 10000
// Number of timeout attempts
export const timeoutNum: number = 3
// Timeout rerequest interval
export const intervalTime: number = 1000
// The operation is normal. The value can be String, Array, and int
export const successCode: NetConfigSuccessCode[] = [200.'200'.'000000']
// The field name of the data state
export const statusName: string = 'code'
// The field name of the status information
export const messageName: string = 'msg'

Copy the code
  1. The wrapper API module is used to manage the request path SRC/API /index.ts
// src/api/index.ts
import common from '@/api/common'

interface UrlDict {
  [key: string]: {
    [key: string]: string
  }
}

const urlDict: UrlDict = {
  common
}

const getUrl = (url: string): string= > {
  try {
    if (url === ' ') throw new Error('Request path is empty')
    const [modelName, urlName] = url.split('. ')
    if (!Object.keys(urlDict).includes(modelName)) throw new Error('Request module not obtained')
    const reqUrl = urlDict[modelName][urlName]
    if(! reqUrl)throw new Error('Requested URL not obtained')
    return reqUrl
  } catch (e) {
    console.error(e)
    return ' '}}export default getUrl

Copy the code
// src/api/common.ts
export default {
  token: '/common/token'
}

Copy the code
  1. Create the required type for the request
// src/types/utils/request.d.ts
declare namespace MyRequest {
  interface response {
    code: number | string,
    msg: string,
    data: any
  }
  class request {
    /** * POST method *@param Url request path, mode: [module name. interface name] for example, common.token *@param Data request parameter *@param Config Requests configuration */public post(url: string, data? : any, config? : object):Promise<response>

    /** * POST method *@param Url request path, mode: [module name. interface name] for example, common.token *@param Params request parameter *@param Config Requests configuration */public get(url: string, params? : any, config? : object):Promise<response>
  }
}

Copy the code
  1. Encapsulates the request
import axios, { AxiosResponse, AxiosRequestConfig, CancelTokenStatic, AxiosInstance } from 'axios'
import {
  baseURL,
  successCode,
  contentType,
  requestTimeout,
  statusName,
  messageName
} from '@/config/net.config'
import qs from 'qs'
import getUrl from '@/api'

const CODE_MESSAGE: any = {
  200: 'Server returned request data successfully'.201: 'Created or modified data successfully'.202: 'A request has been queued in the background (asynchronous task)'.204: 'Data deleted successfully'.400: 'Wrong message'.401: 'User has no permissions (invalid token, incorrect username, password, expired login)'.402: 'Front end painless refresh token'.403: 'User is authorized, but access is forbidden.'.404: 'Access resource does not exist'.406: 'Requested format not available'.410: 'Requested resource permanently deleted and not seen'.500: 'Server error'.502: 'Gateway error'.503: 'Service unavailable, server temporarily overloaded or maintained'.504: 'Gateway timed out'
}

class MyRequest {
  // baseURL will automatically precede url unless the url is an absolute URL.
  protected service: AxiosInstance = axios
  protected pending: ArrayThe < {url: string, cancel: Function }> = []
  protected CancelToken: CancelTokenStatic = axios.CancelToken
  protected axiosRequestConfig: AxiosRequestConfig = {}
  private static _instance: MyRequest;

  constructor () {
    this.requestConfig()
    this.service = axios.create(this.axiosRequestConfig)
    this.interceptorsRequest()
    this.interceptorsResponse()
  }

  /** * Initial configuration *@protected* /
  protected requestConfig (): void {
    this.axiosRequestConfig = {
      baseURL: baseURL,
      headers: {
        timestamp: new Date().getTime(),
        'Content-Type': contentType
      },
      // transformRequest: [obj => qs.stringify(obj)],
      transformResponse: [function (data: AxiosResponse) {
        return data
      }],
      paramsSerializer: function (params: any) {
        return qs.stringify(params, { arrayFormat: 'brackets'})},timeout: requestTimeout,
      withCredentials: false.responseType: 'json'.xsrfCookieName: 'XSRF-TOKEN'.xsrfHeaderName: 'X-XSRF-TOKEN'.maxRedirects: 5.maxContentLength: 2000.validateStatus: function (status: number) {
        return status >= 200 && status < 500
      }
      // httpAgent: new http.Agent({keepAlive: true}),
      // httpsAgent: new https.Agent({keepAlive: true})}}/** * Request interception *@protected* /
  protected interceptorsRequest (): void {
    this.service.interceptors.request.use(
      (config: AxiosRequestConfig) = > {
        const keyOfRequest = this.getKeyOfRequest(config)
        this.removePending(keyOfRequest, true)
        config.cancelToken = new this.CancelToken((c: any) = > {
          this.pending.push({
            url: keyOfRequest,
            cancel: c
          })
        })
        this.requestLog(config)
        return config
      },
      (error) = > {
        return Promise.reject(error)
      }
    )
  }

  /** * Response interception *@protected* /
  protected interceptorsResponse (): void {
    this.service.interceptors.response.use((response: AxiosResponse) = > {
      return this.handleResponse(response)
    }, error= > {
      const { response } = error
      if (response === undefined) {
        return Promise.reject(new Error(error))
      } else {
        return this.handleResponse(response)
      }
    })
  }

  protected handleResponse (response: AxiosResponse): Promise<AxiosResponse<any>> {
    this.responseLog(response)
    this.removePending(this.getKeyOfRequest(response.config))
    const { data, status, config, statusText } = response
    let code = data && data[statusName]
      ? data[statusName]
      : status
    if (successCode.indexOf(data[statusName]) + 1) code = 200
    switch (code) {
      case 200:
        return Promise.resolve(response)
      case 401:
        // The TODO token is invalid. The login page is displayed
        break
      case 403:
        // TODO does not have permission, jump 403 page
        break
    }
    // Exception handling
    const errMsg = data && data[messageName]
      ? data[messageName]
      : CODE_MESSAGE[code]
        ? CODE_MESSAGE[code]
        : statusText
    return Promise.reject(errMsg)
  }

  /** * Cancel repeated requests *@protected
     * @param key
     * @param request* /
  protected removePending (key: string, request: boolean = false) :void {
    this.pending.some((item, index) = > {
      if (item.url === key) {
        if (request) console.log('===== Cancel duplicate request =====', item)
        item.cancel()
        this.pending.splice(index, 1)
        return true
      }
      return false})}/** * get the requested configuration assembly key *@param config
     * @protected* /
  protected getKeyOfRequest (config: AxiosRequestConfig): string {
    let key = config.url
    if (config.params) key += JSON.stringify(config.params)
    if (config.data) key += JSON.stringify(config.data)
    key += `&request_type=${config.method}`
    return key as string
  }

  /** * request log *@param config
     * @protected* /
  protected requestLog (config: any): void{}/** * Response log *@protected
     * @param response* /
  protected responseLog (response: AxiosResponse) {
    if (import.meta.env.MODE === 'development') {
      const randomColor = `rgba(The ${Math.round(Math.random() * 255)}.The ${Math.round(
        Math.random() * 255
      )}.The ${Math.round(Math.random() * 255)}) `
      console.log(
        '% c ┍ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ┑'.`color:${randomColor}; `
      )
      console.log('| request address:, response.config.url)
      console.log('| request parameters:, qs.parse(response.config.data))
      console.log('| return data:, response.data)
      console.log(
        '% c ┕ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ┙'.`color:${randomColor}; `)}}/** * post method *@param url
     * @param data
     * @param config* /
  public post (url: string, data: any = {}, config: object = {}): Promise<MyRequest.response> {
    return new Promise((resolve, reject) = > {
      this.service.post(getUrl(url), data, config).then(result= > {
        resolve({
          msg: result.data.msg,
          data: result.data.data,
          code: result.data.code
        })
      }, reject)
    })
  }

  /** * post method *@param url
     * @param params
     * @param config* /
  public get (url: string, params: any = {}, config: object = {}): Promise<MyRequest.response> {
    return new Promise((resolve, reject) = > {
      this.service.get(`${getUrl(url)}?${qs.stringify(params)}`, config).then(result= > {
        resolve({
          msg: result.data.msg,
          data: result.data.data,
          code: result.data.code
        })
      }, reject)
    })
  }

  /** * Create a unique instance (singleton mode) */
  public static getInstance (): MyRequest {
    Instance is returned directly if it is an instance, if it is not instantiated
    this._instance || (this._instance = new MyRequest())
    return this._instance
  }
}

export default MyRequest.getInstance()

Copy the code
  1. Global registration, here mounted to globalProperties
// src/vab/plugins/globaProperties.ts
import { App } from 'vue'
import request from '@/utils/request'
import router from '@/router'
import { store } from '@/store'
/ * * *@name: sww
 * @date: 2021-06-29
 * @desc: Gets the table height */
const baseTableHeight = (formType: number = 1) :number= > {
  const mainInfo = store.getters.layoutMainInfo
  return (mainInfo.height - 130) * formType
}

/ * * *@name: sww
 * @date: 2021-07-19
 * @desc: Format network resources */
const formatImage = (src: string): string= > {
  if(! src)return ' '
  if (src.includes('http')) return src
  return `The ${import.meta.env.VITE_RES_URL}${src}`
}

const install = (app: App) = > {
  // Register the request instance
  app.config.globalProperties.$request = request
  app.config.globalProperties.$baseTableHeight = baseTableHeight
  app.config.globalProperties.$image = formatImage
}

export default install

Copy the code
  1. Global declaration, if not, use this in the component. No code prompts
// src/types/vab/plugins/globalProperties.d.ts
export {}
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    // code completion configuration
    $request: MyRequest.request,
    $baseTableHeight: (formType? : number) = > number,
    $image: (src: string) = > void}}Copy the code
  1. use
// used in the component
this.$request.post('common.token', {})
this.$request.get('common.token', {})
// use in the ts file
import request from '@/utils/request'
request.post('common.token', {})
request.get('common.token', {})
Copy the code
  1. Notice After adding an API module, import it in API /index.ts, for example, adding a user module
// src/api/user.ts
export default {
  list: '/user/list'
}

Copy the code
// src/api/index.ts
import common from '@/api/common'
// Import the new module
import user from '@/api/user'

interface UrlDict {
  [key: string]: {
    [key: string]: string
  }
}

const urlDict: UrlDict = {
  common,
  user // Add a module
}

/ / use
this.$request.get('user.list', {})
Copy the code