前端通用请求库swagger 基于axios@1扩展 使用此库后可以不用安装axios

npm i -S github:thjjames/swagger或
package.json中dependencies添加
"swagger": "[email protected]:thjjames/swagger"
import Swagger, { RefreshTokenModule, LoadingModule, RaceModule, CacheModule, ErrorModule } from 'swagger';
// Swagger.create suggested but not new keyword, cause param defaults would be lost
const swagger = Swagger.create({
baseURL: 'https://getman.cn/api'
});
swagger.use(RefreshTokenModule).use(ErrorModule);
swagger.$get('/request');
// Vue2
import Vue from 'vue';
Vue.prototype.$swagger = swagger;
this.$swagger.$get('/request');
// Vue3
import { createApp } from 'vue';
const app = createApp({/* ... */});
app.provide('swagger', swagger);
app.config.globalProperties.$swagger = swagger;
this.$swagger.$get('/request');
// React
import React from 'react';
React.Component.prototype.$swagger = swagger;
this.$swagger.$get('/request');参考 https://github.com/axios/axios#creating-an-instance
所有实例均由静态方法create生成,这里舍弃了axios(config)的写法
const swagger = Swagger.create({
baseURL: 'https://getman.cn/api' // 请求基本域名
});swagger.use(module, options);参考 axios.interceptors.use 的执行顺序 为反洋葱模型
swagger.use(LoadingModule).use(RaceModule);模块中的实际执行顺序为:
RaceModule.request-interceptor
↓ ↓ ↓
LoadingModule.request-interceptor
↓ ↓ ↓
ajax(config)
↓ ↓ ↓
LoadingModule.response-interceptor
↓ ↓ ↓
RaceModule.response-interceptor
import { RefreshTokenModule } from 'swagger';
swagger.use(RefreshTokenModule, {
unauthorizedCode: 401,
getRefreshToken() {}
});| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| codeKey | 后端返回data数据中code键名 | string | code |
| unauthorizedCode | 未授权码 | number | 401 |
| maxRetryTimes | 最大重试次数 | number | 1 |
| getRefreshToken | 获取新token方法 | function():Promise | 内置业务方法,一般不通用需要根据实际业务传入 |
import { LoadingModule } from 'swagger';
import { Loading } from 'element-ui';
let loadingInstance = {};
swagger.use(LoadingModule, {
isShowLoading: true,
showLoadingHandler: () => {
loadingInstance = Loading.service();
},
hideLoadingHandler: () => {
loadingInstance.close();
}
});| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| isShowLoading | 是否显示加载状态,可以通过request.config设置单个请求 | boolean | false |
| showLoadingHandler | 展示加载方法 | function | - |
| hideLoadingHandler | 隐藏加载方法 | function | - |
如果
RaceModule开启了全局isAllowRace: true配置又存在手动触发取消请求的场景,请单独对该请求配置isAllowRace: false,否则可能会引起不必要的bug!
import { RaceModule } from 'swagger';
swagger.use(RaceModule, {
isAllowRace: true
});| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| isAllowRace | 是否允许竞态,可以通过request.config设置单个请求 | boolean | false |
| raceKeys | 竞态键值组,键值支持点表示法,可以通过request.config设置单个请求 | array<string> | ['url'] |
| racePosition | 竞态位置,指定被取消的请求位置,可以通过request.config设置单个请求 | 'former' | 'latter' | former |
import { CacheModule } from 'swagger';
swagger.use(CacheModule);| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| isUseCache | 是否使用缓存,通过request.config设置单个请求 | boolean | false |
| cacheKeys | 缓存键值组,键值支持点表示法,可以通过request.config设置单个请求 | array<string> | ['url'] |
| cachePeriod | 缓存时间,由最多2位数字和d | h | m组合表示 | string | 1d |
ErrorModule需要被注册在最后,否则会影响其他模块的使用!
import { ErrorModule } from 'swagger';
import { Message } from 'element-ui';
import router from '@/router';
swagger.use(ErrorModule, {
successfulCode: 0,
forbiddenCode: 403,
forbiddenHandler() {
setTimeout(() => {
router.push({ name: '403' });
});
},
toastHandler: Message.error
});| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| codeKey | 后端返回data数据中code键名 | string | code |
| messageKey | 后端返回data数据中message键名 | string | message |
| successfulCode | 成功码 | number | 0 |
| unauthorizedCode | 未授权码 | number | 401 |
| forbiddenCode | 无权限码 | number | 403 |
| unauthorizedHandler | 未授权处理方法 | function(response) | - |
| forbiddenHandler | 无权限处理方法 | function(response) | - |
| serviceErrorHandler | 业务错误码处理方法,已排除未授权、无权限 | function(response) | - |
| statusErrorHandler | 状态错误码处理方法 | function(response) | - |
| toastHandler | 提示实例方法,可以选择不传由业务触发 | function | - |
除了上述提供的通用模块外,也可以在项目中自由定义任何模块 module,用以抽离繁复的 interceptors.request 或 interceptors.response 里的逻辑,方式很简单:
// module.js
export const CustomModule = function(options = {}) {
this.interceptors.request.use(config => {
// ur custom code
return config;
}, error => {
// ur custom code
return Promise.reject(error);
});
this.interceptors.response.use(response => {
// ur custom code
return response;
}, error => {
// ur custom code
return Promise.reject(error);
});
};
// swagger.js
swagger.use(CustomModule);参考 https://github.com/axios/axios#request-config
目前 swagger 支持的自定义配置有:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| isShowLoading | 是否显示加载状态,可以覆盖loadingModule的全局值 | boolean | false |
| isAllowRace | 是否允许竞态,可以覆盖raceModule的全局值 | boolean | false |
| raceKeys | 竞态键值组,可以覆盖raceModule的全局值 | array<string> | - |
| racePosition | 竞态位置,可以覆盖raceModule的全局值 | 'former' | 'latter' | - |
| isUseCache | 是否使用缓存,无全局值,只可单个设置 | boolean | false |
| cacheKeys | 缓存键值组,可以覆盖CacheModule的全局值 | array<string> | - |
| cachePeriod | 缓存时间,可以覆盖CacheModule的全局值 | string | - |
| isIgnoreToast | 是否忽略提示,用来定制toastHandler作用下的特殊情况 | boolean | false |
axios正常返回数据格式为
{
// the response that was provided by the server
data: {
code: 200,
message: '',
data: {}
},
// the HTTP status code from the server response
status: 200,
// the HTTP status message from the server response
statusText: 'OK',
// the HTTP headers that the server responded with All header names are lowercase and can be accessed using the bracket notation.
// Example: `response.headers['content-type']`
headers: {},
// the config that was provided to `axios` for the request
config: {},
// the request that generated this response
request: {}
}语法糖可以帮助直接返回最里层data数据
this.$swagger.$get(url, config);this.$swagger.$post(url, data, config);please create issues on https://github.com/thjjames/swagger/issues or send an email on [email protected]