Axios 基于promise可以用于浏览器和node.js的网络请求库
参考: Axios 官方文档
一、整合 Axios
1.安装依赖
npm install axios
2.Axios 工具类封装
src同级新建utils文件夹,创建request.ts文件
// src/utils/request.ts
import axios, { InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import { useUserStoreHook } from '@/store/modules/user';
// 创建 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000,
headers: { 'Content-Type': 'application/json;charset=utf-8' }
});
// 请求拦截器
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const userStore = useUserStoreHook();
if (userStore.token) {
config.headers.Authorization = 'XS' + userStore.token;
}
return config;
},
(error: any) => {
console.error('网络错误,请稍后重试');
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const { code, msg } = response.data;
// 登录成功
if (code === '00000') {
return response.data;
}
ElMessage.error(msg || '系统出错');
return Promise.reject(new Error(msg || 'Error'));
},
(error: any) => {
if (error.response.data) {
const { code, msg } = error.response.data;
// token 过期,跳转登录页
if (code === 'A0230') {
ElMessageBox.confirm('当前页面已失效,请重新登录', '提示', {
confirmButtonText: '确定',
type: 'warning'
}).then(() => {
localStorage.clear(); // @vueuse/core 自动导入
window.location.href = '/';
});
}else{
ElMessage.error(msg || '系统出错');
}
}
return Promise.reject(error.message);
}
);
// 导出 axios 实例
export default service;
+++info
3.封装get与post方法
const get = (url, params, _needLoading = true, _needErrorNotify = true) => {
needLoading = _needLoading;
needErrorNotify = _needErrorNotify;
return new Promise((resolve, reject) => {
let _timestamp = new Date().getTime();
service
.get(url, { params })
.then(res => {
if (new Date().getTime() - _timestamp < 200) {
setTimeout(() => {
if (res?.code === 200) {
resolve(res);
} else {
needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
reject(res);
}
}, 200);
} else {
if (res?.code === 200) {
resolve(res);
} else {
needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
reject(res);
}
}
})
.catch(error => {
reject(error);
});
});
};
const post = (url, params, _needLoading = true, _needErrorNotify = true) => {
needLoading = _needLoading;
needErrorNotify = _needErrorNotify;
return new Promise((resolve, reject) => {
let _timestamp = new Date().getTime();
service
.post(url, params)
.then(res => {
if (new Date().getTime() - _timestamp < 200) {
setTimeout(() => {
if (res?.code === 200) {
resolve(res);
} else {
needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
reject(res);
}
}, 200);
} else {
if (res?.code === 200) {
resolve(res);
} else {
needErrorNotify && res && res.msg && $uiMsg.error(res.msg);
reject(res);
}
}
})
.catch(error => {
reject(error);
});
});
};
export { get, post };
+++
二、使用 Axios
1.定义请求参数类型与返回数据类型
// src/api/auth/types.ts
// or src/api/model/userModel.ts
/**
* 登录请求参数
*/
export interface LoginData {
/**
* 用户名
*/
username: string;
/**
* 密码
*/
password: string;
}
/**
* 登录响应
*/
export interface LoginResult {
/**
* 访问token
*/
accessToken?: string;
/**
* 过期时间(单位:毫秒)
*/
expires?: number;
/**
* 刷新token
*/
refreshToken?: string;
/**
* token 类型
*/
tokenType?: string;
}
2.API 定义
// src/api/auth/index.ts
// or src/api/user.ts
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { LoginData, LoginResult } from './types';
/**
* 登录API
*
* @param data {LoginData}
* @returns
*/
export function loginApi(data: LoginData): AxiosPromise<LoginResult> {
return request({
url: '/api/v1/auth/login',
method: 'post',
params: data
});
}
3.API 调用
// src/store/modules/user.ts
import { loginApi } from '@/api/auth';
import { LoginData } from '@/api/auth/types';
/**
* 登录调用
*
* @param {LoginData}
* @returns
*/
function login(loginData: LoginData) {
return new Promise<void>((resolve, reject) => {
loginApi(loginData)
.then(response => {
const { tokenType, accessToken } = response.data;
token.value = tokenType + ' ' + accessToken; // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
resolve();
})
.catch(error => {
reject(error);
});
});
}