自定义 mock

352 阅读1分钟

自定义 mock

手动实现一个mock功能,不使用 mock.js、Apifox 等 mock 平台,根据 axios 拦截器和faker

  1. 下载 fakeraxios

    使用faker参见 fakerjs.dev

    npm i @faker-js/faker axios
    
  2. 创建 mock.ts 文件用来 mock 数据

    import { faker } from '@faker-js/faker'
    import { AxiosRequestConfig } from 'axios'
    
    type Mock = (config: AxiosRequestConfig) => [number, any]
    faker.setLocale('zh_CN')
    // mock数据
    export const mockItemIndexBalance: Mock = (config) => {
      return [
        200,
        {
          expenses: 9900,
          income: 9900,
          balance: 0
        }
      ]
    }
    
  3. 创建 mock 方法

    import { AxiosResponse } from 'axios'
    import { mockSession } from './mock'
    
    const mock = (response: AxiosResponse) => {
      const whiteList = ['localhost', '127.0.0.1']
      // 本地开发mock
      if (!whiteList.includes(location.hostname)) {
        return false
      }
      switch (response.config?.params?._mock) {
        case 'itemIndexBalance':
          ;[response.status, response.data] = mockItemIndexBalance(response.config)
          return true
        default:
          return false
      }
    }
    
  4. 创建 axios 实例,并添加拦截器

    拦截响应数据,返回 mock 数据

    /* 封装的axios... */
    http.instance.interceptors.response.use(
      (response) => {
        mock(response)
        if (response.status >= 400) {
          throw { response }
        } else {
          return response
        }
      },
      (error) => {
        mock(error.response)
        if (error.response.status >= 400) {
          throw error
        } else {
          return error.response
        }
      }
    )
    
  5. 使用 mock

    // Item.tsx
    // 发起请求
    const response = await http.get(
      '/items/balance',
      {
        happen_after: '2022-12-01 00:00:00',
        happen_before: '2022-12-05 00:00:00',
        page: 1
      },
      {
        _mock: 'itemIndexBalance'
      }
    )
    
  6. 类型支持

    实践的技术栈 Vue3+Vite+TSX

    • /src目录下新建 custom.d.ts用来扩展 Axios 的类型

      // custom.d.ts
      import { AxiosRequestConfig } from 'axios'
      declare module 'axios' {
        export interface AxiosRequestConfig {
          _autoLoading?: boolean
          _mock?: string
        }
      }