Skip to content

request请求

Mock

平台使用 vite-plugin-mock 插件集成了 mockjs,支持常用的 postget 请求方式,仅用于本地开发。生产环境在env设置VITE_USE_MOCK = false

注意

平台将 vite-plugin-mock 插件本地化了,不在从 npm 包下载,这样做是为了自动化部署时,其他插件的 esbuildvite-plugin-mockesbuild 版本不一致,导致安装依赖时,速度慢或者报错等情况。

生产环境 Mock 可以和真实接口共存吗?

当然可以共存,不过可能会遇到 Mock 干扰真实接口的问题。如果您在开发环境接口没问题,但是到生产环境出问题了,可以设置环境变量 VITE_USE_MOCK = false 即可。

基础用法

注意

平台在请求mock时,多加了一层前缀 mock-server ,例如 mock 地址:/mock-server/**

  1. /mock/datasSource/**/ 新建 *.ts 文件

  2. 新增 post 请求

typescript
import { getMockRequest } from '@gx-mock/util/utils'

export default [
  getMockRequest({
    url: '/radar',
    method: 'get',
    callback: () => {
      return {
        data: radarData
      } // 这里可以返回data,也可以不用写data,直接返回需要的数据,当然也可以自定义code、以及message;callback会做相应的处理
    }
  })
]
  1. /src/services/ 新建 indes.ts 文件
typescript
import request from '@/utils/request'

export function getList(data) {
  return request({
    url: '/fake_list_Detail',
    method: 'post',
    isMock: true, // mock 请求设置为 true
    data
  })
}
  1. 在页面上引入
vue
<script setup lang="ts">
import { getList } from "@/services";

async function onTest() {
  const response: ResponseResult<{
    name: string;
  }> = await getList({ username: "admin", password: "admin123" });
  if (response) {
    console.log(response.data)
  }
}
</script>

<template>
  <el-button @click="onTest">点击测试</el-button>
</template>

可以看到页面中引入了 ResponseResult 类型,可以在使用找中获得类型提示,如下图

Requst

平台封装了 axios

Request 类型

点击查看具体信息

代码实现

typescript
import type {
  AxiosRequestConfig,
  AxiosResponse,
  AxiosInstance,
  AxiosPromise,
  AxiosError,
  Method,
  AxiosInterceptorManager,
  AxiosInterceptorOptions,
  InternalAxiosRequestConfig
} from 'axios'

export interface GAxiosResponse<T = any> extends Omit<AxiosResponse, 'data' | 'config'> {
  data: T;
  config: Omit<GAxiosOptions, 'headers'>;
}

export type CancelOptions = { cancel: (key?: string) => void, cancelAll: () => void; reset: () => void }

export type XhtInstance = {
  /**
   * @Author      gx12358
   * @DateTime    2023/1/6
   * @lastTime    2023/1/6
   * @description 请求之前处理config
   */
  beforeRequestHook?: (config: GAxiosOptions) => GAxiosOptions;

  /**
   * @Author      gx12358
   * @DateTime    2023/11/3
   * @lastTime    2023/11/3
   * @description 请求之前返回cancel函数
   */
  cancelCallBackHook?: ({ cancel, cancelAll, reset }: CancelOptions) => void;

  /**
   * @description: 处理响应数据
   */
  transformResponseHook?: (res: GAxiosResponse, options: Partial<GAxiosOptions>) => any;

  /**
   * @description: 请求失败处理
   */
  requestCatchHook?: (e: Error) => boolean;

  /**
   * @description: 请求之前的拦截器
   */
  requestInterceptors?: (config: GAxiosOptions) => GAxiosOptions;

  /**
   * @description: 请求之后的拦截器
   */
  responseInterceptors?: (res: GAxiosResponse) => GAxiosResponse;

  /**
   * @description: 请求之前的拦截器错误处理
   */
  requestInterceptorsCatch?: (error: AxiosError) => void;

  /**
   * @description: 请求之后的拦截器错误处理
   */
  responseInterceptorsCatch?: (axiosInstance: GAxiosInstance, error: AxiosError) => void;
}

export interface GAxiosOptions extends Omit<AxiosRequestConfig, 'headers' | 'method'> {
  headers?: Record<string, any>;
  method: Method;
  isMock?: boolean; // 是否是mock
  retry?: boolean; // 是否是重试接口
  isReturnNativeResponse?: boolean; // 直接返回response,不作任何处理(包含响应值等基本信息)
  customize?: boolean; // 直接返回response.data(接口返回值),错误不做统一提示
  carryToken?: boolean; // 是否携带token
  prefix?: string; // 接口自定义前缀
  ignoreCancelToken?: boolean; // 忽略重复请求
  cancelKey?: string; // 取消请求key(用来需要请求)
  /**
   * @Author      gx12358
   * @DateTime    2023/1/6
   * @lastTime    2023/1/6
   * @description 请求之前处理config
   */
  beforeRequestHook?: XhtInstance['beforeRequestHook'];

  /**
   * @Author      gx12358
   * @DateTime    2023/11/3
   * @lastTime    2023/11/3
   * @description 请求之前返回cancel函数
   */
  cancelCallBackHook?: XhtInstance['cancelCallBackHook'];

  /**
   * @description: 处理响应数据
   */
  transformResponseHook?: XhtInstance['transformResponseHook'];

  /**
   * @description: 请求失败处理
   */
  requestCatchHook?: XhtInstance['requestCatchHook'];

  /**
   * @description: 请求之前的拦截器
   */
  requestInterceptors?: XhtInstance['requestInterceptors'];

  /**
   * @description: 请求之后的拦截器
   */
  responseInterceptors?: XhtInstance['responseInterceptors'];

  /**
   * @description: 请求之前的拦截器错误处理
   */
  requestInterceptorsCatch?: XhtInstance['requestInterceptorsCatch'];

  /**
   * @description: 请求之后的拦截器错误处理
   */
  responseInterceptorsCatch?: XhtInstance['responseInterceptorsCatch'];
}

export interface GAxiosInstance extends Omit<AxiosInstance, 'interceptors'> {
  (config: GAxiosOptions): AxiosPromise<ResponseResult>;

  (url: string, config?: GAxiosOptions): AxiosPromise<ResponseResult>;

  interceptors: {
    request: Omit<AxiosInterceptorManager<InternalAxiosRequestConfig>, 'use'> & {
      use<V>(
        onFulfilled?: ((value: V) => V | Promise<V>) | null,
        onRejected?: ((error: any) => any) | null,
        options?: AxiosInterceptorOptions
      ): number;
    };
    response: Omit<AxiosInterceptorManager<AxiosResponse>, 'use'> & {
      use<V>(
        onFulfilled?: ((value: V) => V | Promise<V>) | null,
        onRejected?: ((error: any) => any) | null,
        options?: AxiosInterceptorOptions
      ): number;
    };
  }
}

/**
 * @description: request method
 */
export enum RequestEnum {
  GET = 'GET',
  POST = 'POST',
  PUT = 'PUT',
  DELETE = 'DELETE',
}

/**
 * @description:  contentType
 */
export enum ContentTypeEnum {
  // json
  JSON = 'application/json;charset=UTF-8',
  // form-data qs
  FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
}

Request 传参 (集成 axios 参数)

request 源码,参数解析如下

参数属性说明类型
headers请求头Record<string, any>
method请求方式RequestMethods
url请求地址string
param请求参数AxiosRequestConfig
data请求参数AxiosRequestConfig
isMock是否是mock请求boolean
retry是否是重试接口boolean
prefix接口自定义前缀string
isReturnNativeResponse直接返回response,不作任何处理(包含响应值等基本信息)boolean
customize直接返回response.data(接口返回值),错误不做统一提示boolean
carryToken是否携带tokenboolean
cancelKey取消请求key(用来需要请求)string
ignoreCancelToken忽略重复请求boolean
beforeRequestHook请求之前处理config(config: GAxiosOptions) => GAxiosOptions;
cancelCallBackHook请求之前返回cancel函数({ cancel, cancelAll, reset }: CancelOptions) => void;
transformResponseHook处理响应数据(res: AxiosResponse, options: GAxiosOptions) => any;
requestCatchHook请求失败处理(e: Error) => boolean;
requestInterceptors请求之前的拦截器(config: GAxiosOptions) => GAxiosOptions
responseInterceptors请求之后的拦截器(res: AxiosResponse) => AxiosResponse;
requestInterceptorsCatch请求之前的拦截器错误处理(error: Error) => void;
responseInterceptorsCatch请求之后的拦截器错误处理(axiosInstance: GAxiosInstance, error: Error) => void;

TIP

参数 beforeRequestHook transformResponseHook requestCatchHook requestInterceptors responseInterceptors requestInterceptorsCatch responseInterceptorsCatch 已在代码内实现基本的,原则上不需要传。想定制化的可以在这里同意修改。

Reponse 类型 用法参考Mock中的 ④ 步

点击查看具体信息

代码实现

typescript
declare interface ResponseResult<T = any> extends TableResult<T> {
  code: number;
  msg?: string;
  message?: string;
  data?: T;
  roles?: any;
  user?: any;
  permissions?: any;
}

declare interface TableResult<T = any> {
  total?: number;
  pageNum?: number;
  rows?: T;
}

Proxy 代理

Proxy 代理 用来解决开发阶段与后端联调,跨域问题。

基础用法

  1. /src/default/defaultSettings.ts 设置代理地址
typescript
const settings = {
  //开启proxy
  useProxy: true,
  // proxy target
  proxyTarget: 'http://127.0.0.1:3000',
}
  1. .env.development 配置 VITE_BASE_URL
# api前缀
VITE_BASE_URL=/api

平台Token

  1. token 相关信息配置 (/src/default/defaultSettings.ts)
typescript
const settings = {
  //不经过token校验的路由
  routesWhiteList: [ '/user/login', '/user/register', '/exception/404', '/exception/403' ],
  //token名称
  tokenName: 'Authorization',
  //token在localStorage、sessionStorage、cookie存储的key的名称
  tokenTableName: 'GxAccessToken',
  //token存储位置localStorage sessionStorage cookie
  storage: 'localStorage',
}
  1. token store 存储
点击查看详情

代码实现分别在: