随手记:一些Vue或Nuxt的Axios封装
虽然Nuxt3自带$fetch,但某些特定场景比如需要上传进度的文件上传功能需要用到axios
标准函数方法,可能不适用于nuxt
// utils/http.ts
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from 'axios';
import axios from 'axios';
import { PageEnum } from '@/enums/pageEnum';
import { RequestCodeEnum } from '@/enums/requestEnum';
import { config } from '@/config'
interface ResponseType<T = any> {
code: RequestCodeEnum;
data: T;
msg: string;
show: 1 | 0;
}
// 创建 Axios 实例
const instance: AxiosInstance = axios.create({
baseURL: `${config.apiBase}${config.apiPrefix}`,
timeout: 10 * 60 * 1000, // 请求超时时间
});
// 请求拦截器
instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 在发送请求前可以在这里添加全局配置,比如添加 Token
const userStore = useUserStore();
const token = userStore.token;
if (token) {
config.headers.set('Token', token);
}
return config;
},
(error) => {
// 请求错误处理
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
(response: AxiosResponse<ResponseType>) => {
const showMessage = response.data.show;
const message = response.data.msg;
const userStore = useUserStore();
const resultData = response.data.data;
const codeMap = {
[RequestCodeEnum.SUCCESS]: () => {
isClient(() => {
if (showMessage === 1) {
useMessage().success(message);
}
});
},
[RequestCodeEnum.FAIL]: () => {
isClient(() => {
if (showMessage === 1) {
useMessage().error(message);
}
});
Promise.reject(message);
},
[RequestCodeEnum.LOGIN_FAILURE]: () => {
isClient(() => {
userStore.logout(true);
});
Promise.reject(message);
},
[RequestCodeEnum.NOT_INSTALL]: () => {
isClient(() => {
window.location.replace(PageEnum.INSTALL);
});
},
[RequestCodeEnum.OPEN_NEW_PAGE]: () => {
isClient(() => {
window.open(
typeof resultData === 'string' ? resultData : (resultData as any).url
);
});
},
}[response.data.code];
if (codeMap) {
codeMap();
} else {
Promise.reject(message);
}
return response.data.data;
},
(error) => {
return Promise.reject(error);
}
);
// 封装通用请求方法
const useAxios = {
get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
return instance.get(url, { params, ...config });
},
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return instance.post(url, data, { ...config });
},
upload<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
const formData = new FormData();
if (data) {
Object.keys(data).forEach((key) => {
formData.append(key, data[key]);
});
}
return instance.post(url, data, { ...config });
},
};
export default useAxios;
Class版本,new的时候才产生实例,所以不影响Nuxt3使用
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from 'axios';
import axios from 'axios';
import { PageEnum } from '~/enums/pageEnum';
import { RequestCodeEnum } from '~/enums/requestEnum';
interface ResponseType<T = any> {
code: RequestCodeEnum;
data: T;
msg: string;
show: 1 | 0;
}
export class AxiosService {
private instance: AxiosInstance;
constructor() {
this.instance = axios.create({
timeout: 10 * 60 * 1000,
});
this.setupInterceptors();
}
// 设置拦截器
private setupInterceptors() {
// 请求拦截器
this.instance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const runtimeConfig = useRuntimeConfig();
config.baseURL = `${runtimeConfig.public.apiBase}${runtimeConfig.public.apiPrefix}`;
const userStore = useUserStore();
const token = userStore.token;
if (token) {
config.headers.set('Token', token);
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
this.instance.interceptors.response.use(
(response: AxiosResponse<ResponseType>) => {
const showMessage = response.data.show;
const message = response.data.msg;
const userStore = useUserStore();
const resultData = response.data.data;
const codeMap = {
[RequestCodeEnum.SUCCESS]: () => {
isClient(() => {
if (showMessage === 1) {
useMessage().success(message);
}
});
},
[RequestCodeEnum.FAIL]: () => {
isClient(() => {
if (showMessage === 1) {
useMessage().error(message);
}
});
return Promise.reject(message);
},
[RequestCodeEnum.LOGIN_FAILURE]: () => {
isClient(() => {
userStore.logout(true);
});
return Promise.reject(message);
},
[RequestCodeEnum.NOT_INSTALL]: () => {
isClient(() => {
window.location.replace(PageEnum.INSTALL);
});
},
[RequestCodeEnum.OPEN_NEW_PAGE]: () => {
isClient(() => {
window.open(
typeof resultData === 'string'
? resultData
: (resultData as any).url
);
});
},
}[response.data.code];
if (codeMap) {
codeMap();
} else {
return Promise.reject(message);
}
return response.data.data;
},
(error) => {
return Promise.reject(error);
}
);
}
// 通用 GET 请求
public get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
return this.instance.get(url, { params, ...config });
}
// 通用 POST 请求
public post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return this.instance.post(url, data, { ...config });
}
// 上传请求
public upload<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
const formData = new FormData();
if (data) {
Object.keys(data).forEach((key) => {
formData.append(key, data[key]);
});
}
return this.instance.post(url, formData, {
...config,
headers: {
'Content-Type': 'multipart/form-data',
...(config?.headers || {}),
},
});
}
}
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。