主题
与服务端交互
框架使用 @pubinfo/openapi
来实现与服务端的交互。核心具有如下功能
- 自动扫描生成请求文件,无需手动编写请求文件
- 自动引入请求函数,无需手动引入。
- 丰富的请求策略,支持分页、缓存、Token认证、无感刷新Token、上传策略、断点续传、请求重试等功能。
设置 baseURL
在根目录.env.*
文件里的 VITE_APP_API_BASEURL
这个参数就是配置请求的 baseURL
。
例如项目的真实接口请求地址为:
则可设置为 VITE_APP_API_BASEURL = http://api.test.com/
OpenAPI 配置
如果关闭了运行时自动生成接口文件,可以通过
pnpm run openapi
指令手动生成。
在应用目录下 apps/*/openapi.config.ts
文件里配置 openapi
的参数。
详细配置请查看 OpenAPI使用指南 文档。
注意
openapi
只在开发环境下启动,生产环境下不会生成接口文件。
扫描接口文档hash值和本地生成文件hash是否有区别,如果有区别则重新生成文件。如果需要强制重新生成文件,可以删除 src/api/modules
目录下的文件。
ts
import { defineConfig } from '@pubinfo/openapi'
export default defineConfig({
imports: { '@/api': 'request' },
batch: [
{
input: 'http://124.223.184.245:10003/pubinfo-sys/v3/api-docs/auth',
output: './src/api/modules/auth',
},
{
input: 'http://124.223.184.245:10003/pubinfo-sys/v3/api-docs/log',
output: './src/api/modules/log',
},
{
input: 'http://124.223.184.245:10003/pubinfo-sys/v3/api-docs/rbac',
output: './src/api/modules/rbac',
},
{
input: 'http://124.223.184.245:10003/pubinfo-sys/v3/api-docs/assist',
output: './src/api/modules/assist',
},
],
})
Request
@pubinfo/openapi
封装了一些通用方法 Typescript支持、响应缓存、无感数据交互、分页请求策略、Token认证拦截、无感刷新Token、通用的上传策略、自动拉取数据、断点续传策略、跨组件传值、自动拉取数据、请求重试等功能。
@pubinfo/openapi
生成的接口文件会通过 unplugin-auto-import
自动导入到 vite
项目中,不需要手动导入。
详细配置请查看 OpenAPI使用指南 文档。
拦截器
在 /src/api/index.ts
文件里实例化了 @pubinfo/openapi
对象,并对 request
和 response
设置了拦截器,拦截器的用处就是拦截每一次的请求和响应,然后做一些全局的处理。例如接口响应报错,可以在拦截器里用统一的报错提示来展示,方便业务开发。但因为每个公司和部门提供的接口标准不同,所以该文件拦截器部分的代码,需要开发者根据实际情况去修改调整。
代码很简单,首先初始化请求对象,然后 beforeRequest
和 responded
就分别是请求和响应的拦截代码了。
配套的权限管理系统做了双 token
的处理,token
和 refreshToken
,token
用于请求接口,refreshToken
用于刷新 token
,token
过期后,会自动刷新 token
,然后重新请求接口。
不同的响应code编码,统一放置在 src/api/enum/code.ts
文件里,方便统一管理。
ts
export enum RESPONSE_CODE {
/**
* @description
* 接口请求成功
*/
SUCCESS = 0,
/**
* @description
* 运行异常
*/
ERROR = -1,
/**
* @description
* 操作失败,业务异常
*/
BUSINESS_ERROR = 4,
/**
* @description
* 账户锁定,请联系管理员
*/
ACCOUNT_LOCKED = 400001001,
/**
* @description
* 登录名或密码不正确
*/
LOGINNAME_PASSWORD_WRONG = 400001002,
/**
* @description
* 账户未启用,请联系管理员
*/
ACCOUT_NOT_ENABLE = 400001003,
/**
* @description
* token已过期
*/
ACCESS_TOKEN_INVALID = 400001006,
/**
* @description
* 刷新refreshToken已过期
*/
LOGIN_TOKEN_INVALID = 400001004,
/**
* @description
* 访问未授权
*/
UNAUTHORIZED_ACCESS = 400001007,
/**
* @description
* 验证码失效
*/
CODE_OVERTIME = 400002001,
/**
* @description
* 验证码不匹配
*/
CODE_WRONG = 400002002,
/**
* @description
* 首次登录,请修改初始密码
*/
CHANGE_INIT_PASSWORD = 400003001,
/**
* @description
* 登录密码已过期,请修改密码
*/
PASSWORD_EXPIRED = 400003002,
}
跨域处理
生产环境的跨域需要服务端去解决,开发环境的跨域问题可在本地设置代理解决。如果本地开发环境请求接口提示跨域,可以设置 .env.development
文件里 VITE_OPEN_PROXY = true
开启代理。
ts
api.get('news/list') // http://localhost:9000/proxy/news/list
api.post('news/add') // http://localhost:9000/proxy/news/add
开启代理后,原有请求都会被指向到本地 http://localhost:5173/proxy
,因为 /proxy
匹配到了 vite.config.ts
里代理部分的设置,所以实际是请求依旧是 VITE_APP_API_BASEURL
所设置的地址。
javascript
export default {
server: {
// vite.config.ts 中 proxy 配置,该配置即用于代理 API 请求
proxy: {
'/proxy': {
target: loadEnv(mode, process.cwd()).VITE_APP_API_BASEURL,
changeOrigin: command === 'serve' && loadEnv(mode, process.cwd()).VITE_OPEN_PROXY === 'true',
rewrite: path => path.replace(/\/proxy/, ''),
},
},
}
}
Mock
Mock
数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发所阻塞。
提示
系统使用 vite-plugin-fake-server
提供开发和生产模拟服务。
Mock 数据编写规则请阅读 Mockjs
官方文档。
开发环境 mock
mock
文件存放在 /src/mock/
下,建议按照不同模块区分文件夹。文件新增或修改后会自动更新,不需要手动重启,可以在代码控制台查看日志信息。
以下为示例代码:
ts
import { defineFakeRoute } from 'vite-plugin-fake-server/client'
import Mock from 'mockjs'
export default defineFakeRoute([
{
url: '/mock/news/list',
method: 'get',
response: () => {
return {
error: '',
code: 0,
data: Mock.mock({
'list|5-10': [
{
title: '@ctitle',
},
],
}),
}
},
},
])
为了让 mock
接口与真实接口共存,即项目开发中,部分请求 mock
接口,部分请求真实接口。需要在配置 mock
接口的时候,给 url
参数统一设置 /mock/
前缀,并在调用接口的时候,使用 baseURL
强制修改此次请求的地址。
如下所示,其中 app/menu/list
会请求本地的 mock 接口,而 app/route/list
依旧请求真实接口,即使开启跨域代理也不影响。
ts
import request from '@/api'
/**
* @description 后端获取路由数据
*/
export function GetApiRouteList(options?: { [key: string]: any }) {
return request.Get<API.RouteList>('app/route/list', {
...(options || {}),
})
}
/**
* @description 后端获取路由数据
*/
export function GetApiMenuList(options?: { [key: string]: any }) {
return request.Get<API.MenuList>('app/menu/list', {
baseURL: '/mock',
...(options || {}),
})
}
生产环境 mock
注意
生产环境一般都是调用真实接口,如果需要使用 mock
也只适用于一些简单的示例网站及预览网站。
需要注意一点,如果项目中有涉及到上传功能,请彻底关闭线上环境 mock
,在环境配置里设置 VITE_BUILD_MOCK = false
,不然线上环境将会报错。
默认已经配置好生产环境 mock
,如果不想让生产环境里的请求走 mock
,可在接口调用处删除 baseURL
设置,或直接删除 mock
接口文件。
开发环境与生产环境使用 mock
差异不大,比较大的区别是生产环境里调用 mock
接口,在控制台内看不到接口请求日志。
多服务
在后端是微服务下,basicURL
会有多个,可以在 openapi.config.ts
文件里配置多个 batch
,每个 batch
对应一个服务。
示例说明
下面是一个示例,有两个服务,一个是 pubinfo-auth
服务,一个是 pubinfo-sys
服务。 pubinfo-sys
提供 rbac
、assist
、configData
、log
四个模块的接口。 pubinfo-auth
提供 auth
模块的接口。
设置ENV 环境变量
设置 env
和 env.development
文件里的 VITE_APP_API_BASEURL
和 VITE_APP_API_BASEURL_AUTH
VITE_APP_API_BASEURL
为 pubinfo-sys
服务地址,VITE_APP_API_BASEURL_AUTH
为 pubinfo-auth
服务地址。
env
# 接口请求地址,会设置到 axios 的 baseURL 参数上
VITE_APP_API_BASEURL = http://124.223.184.245:20010/api/pubinfo-sys
VITE_APP_API_BASEURL_AUTH = http://124.223.184.245:20010/api/pubinfo-auth
创建请求实例
在 api/request/index.ts
文件里,可以通过 import.meta.env
来获取环境变量,并生成请求实例
ts
import { createRequest } from '@/api/factory'
const basic = createRequest(import.meta.env.VITE_APP_API_BASEURL)
const auth = createRequest(import.meta.env.VITE_APP_API_BASEURL_AUTH)
export {
basic,
auth,
}
配置 openapi.config.ts
ts
import { presetName } from '@pubinfo/preset-openapi'
import { defineConfig } from '@pubinfo/openapi'
export default defineConfig({
enabled: false,
presets: [
presetName({
functionName: 'camelCase',
}),
],
imports: { '@/api/request': [{ name: 'basic', as: 'request' }] },
batch: [
{
input: 'http://124.223.184.245:20010/api/pubinfo-auth/v3/api-docs/auth',
output: './src/api/modules/auth',
imports: { '@/api/request': [{ name: 'auth', as: 'request' }] },
},
{
input: 'http://124.223.184.245:20010/api/pubinfo-sys/v3/api-docs/rbac',
output: './src/api/modules/rbac',
},
{
input: 'http://124.223.184.245:20010/api/pubinfo-sys/v3/api-docs/assist',
output: './src/api/modules/assist',
},
{
input: 'http://124.223.184.245:20010/api/pubinfo-sys/v3/api-docs/configData',
output: './src/api/modules/configData',
},
{
input: 'http://124.223.184.245:20010/api/pubinfo-sys/v3/api-docs/log',
output: './src/api/modules/log',
},
],
hooks: {
customType(schema, namespace, defaultFn) {
// `int64` 在前端会精度丢失,可在此处调整对应字段的 `TS类型`
if (schema?.type === 'integer' && schema?.format === 'int64')
return 'number'
return defaultFn(schema, namespace)
},
},
})
生成接口文件
执行 pnpm run openapi
生成接口文件,然后就可以在项目中使用了。
代理
配置代理需要使用统一前缀VITE_APP_API_
以VITE_APP_API_
为开头的请求basicUrl
会在开启VITE_OPEN_PROXY
后自动代理到对应的服务上。
例如:
VITE_APP_API_BASEURL = http://124.223.184.245:20010/api/pubinfo-sys
VITE_APP_API_BASEURL_AUTH = http://124.223.184.245:20010/api/pubinfo-auth