目录
一、安装Axios和js-cookie
npm install --save js-cookie
npm install --save @types/js-cookie
npm install axios
二、axios工具封装
在src下新建utils文件夹,然后在utils文件下新建auth.ts、request.ts,内容如下:
// src/utils/auth.ts
import Cookies from 'js-cookie';
const TokenKey = 'vue3-element-admin-token';
export function getToken() {
return Cookies.get(TokenKey);
}
export function setToken(token: string) {
Cookies.set(TokenKey, token);
}
export function removeToken() {
return Cookies.remove(TokenKey);
}
// src/utils/request.ts
import axios, { AxiosRequestConfig,InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getToken } from '@/utils/auth';
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<any>) => {
if (!config.headers) {
throw new Error(
`Expected 'config' and 'config.headers' not to be undefined`
);
}
const user = useUserStoreHook();
if (user.token) {
(config.headers as any).Authorization = getToken();
}
return config;
},
(error: any) => {
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const { code, msg } = response.data;
if (code === '00000') {
return response.data;
} else {
// 响应数据为二进制流处理(Excel导出)
if (response.data instanceof ArrayBuffer) {
return response;
}
ElMessage({
message: msg || '系统出错',
type: 'error'
});
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: 'OK',
type: 'warning'
}).then(() => {
localStorage.clear();
window.location.href = '/';
});
} else {
ElMessage({
message: msg || '系统出错',
type: 'error'
});
}
}
return Promise.reject(error.message);
}
);
// 导出 axios 实例
export default service;
三、API封装
以登录、并获取用户信息(昵称、头像、角色集合和权限集合)的接口为案例,演示如何通过封装的 axios 工具类请求后端接口,获取响应数据。
①在src下新建types文件夹,然后在types文件夹下新建global.d.ts内容如下:
declare global {
interface PageQuery {
pageNum: number;
pageSize: number;
}
interface PageResult<T> {
list: T;
total: number;
}
type DialogType = {
title?: string;
visible: boolean;
};
type OptionType = {
value: string;
label: string;
checked?: boolean;
children?: OptionType[];
};
}
export {};
②在src下新建api文件夹,然后在api下新建auth文件夹,然后在auth文件夹下新建index.ts和types.ts,内容如下:
// src/api/auth/index.ts
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { LoginData, TokenResult, VerifyCode } from './types';
/**
*
* @param data {LoginForm}
* @returns
*/
export function loginApi(data: LoginData): AxiosPromise<TokenResult> {
return request({
url: '/api/v1/auth/login',
method: 'post',
params: data
});
}
/**
* 注销
*/
export function logoutApi() {
return request({
url: '/api/v1/auth/logout',
method: 'delete'
});
}
/**
* 获取图片验证码
*/
export function getCaptcha(): AxiosPromise<VerifyCode> {
return request({
url: '/captcha?t=' + new Date().getTime().toString(),
method: 'get'
});
}
// src/api/auth/types.ts
/**
* 登录数据类型
*/
export interface LoginData {
username: string;
password: string;
/**
* 验证码Code
*/
//verifyCode: string;
/**
* 验证码Code服务端缓存key(UUID)
*/
// verifyCodeKey: string;
}
/**
* Token响应类型
*/
export interface TokenResult {
accessToken: string;
refreshToken: string;
expires: number;
}
/**
* 验证码类型
*/
export interface VerifyCode {
verifyCodeImg: string;
verifyCodeKey: string;
}
③在api下新建user文件夹,然后在user文件夹下新建index.ts和types.ts,内容如下:
// src/api/user/index.ts
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { UserForm, UserInfo, UserPageResult, UserQuery } from './types';
/**
* 登录成功后获取用户信息(昵称、头像、权限集合和角色集合)
*/
export function getUserInfo(): AxiosPromise<UserInfo> {
return request({
url: '/api/v1/users/me',
method: 'get'
});
}
/**
* 获取用户分页列表
*
* @param queryParams
*/
export function listUserPages(
queryParams: UserQuery
): AxiosPromise<UserPageResult> {
return request({
url: '/api/v1/users/pages',
method: 'get',
params: queryParams
});
}
/**
* 获取用户表单详情
*
* @param userId
*/
export function getUserForm(userId: number): AxiosPromise<UserForm> {
return request({
url: '/api/v1/users/' + userId + '/form',
method: 'get'
});
}
/**
* 添加用户
*
* @param data
*/
export function addUser(data: any) {
return request({
url: '/api/v1/users',
method: 'post',
data: data
});
}
/**
* 修改用户
*
* @param id
* @param data
*/
export function updateUser(id: number, data: UserForm) {
return request({
url: '/api/v1/users/' + id,
method: 'put',
data: data
});
}
/**
* 修改用户状态
*
* @param id
* @param status
*/
export function updateUserStatus(id: number, status: number) {
return request({
url: '/api/v1/users/' + id + '/status',
method: 'patch',
params: { status: status }
});
}
/**
* 修改用户密码
*
* @param id
* @param password
*/
export function updateUserPassword(id: number, password: string) {
return request({
url: '/api/v1/users/' + id + '/password',
method: 'patch',
params: { password: password }
});
}
/**
* 删除用户
*
* @param ids
*/
export function deleteUsers(ids: string) {
return request({
url: '/api/v1/users/' + ids,
method: 'delete'
});
}
/**
* 下载用户导入模板
*
* @returns
*/
export function downloadTemplate() {
return request({
url: '/api/v1/users/template',
method: 'get',
responseType: 'arraybuffer'
});
}
/**
* 导出用户
*
* @param queryParams
* @returns
*/
export function exportUser(queryParams: UserQuery) {
return request({
url: '/api/v1/users/_export',
method: 'get',
params: queryParams,
responseType: 'arraybuffer'
});
}
/**
* 导入用户
*
* @param file
*/
export function importUser(deptId: number, roleIds: string, file: File) {
const formData = new FormData();
formData.append('file', file);
formData.append('deptId', deptId.toString());
formData.append('roleIds', roleIds);
return request({
url: '/api/v1/users/_import',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}
// src/api/user/types.ts
/**
* 登录用户信息
*/
export interface UserInfo {
nickname: string;
avatar: string;
roles: string[];
perms: string[];
}
/**
* 用户查询参数
*/
export interface UserQuery extends PageQuery {
keywords: string;
status: number;
deptId: number;
}
/**
* 用户分页列表项声明
*/
export interface UserType {
id: string;
username: string;
nickname: string;
mobile: string;
gender: number;
avatar: string;
email: string;
status: number;
deptName: string;
roleNames: string;
createTime: string;
}
/**
* 用户分页项类型声明
*/
export type UserPageResult = PageResult<UserType[]>;
/**
* 用户表单类型声明
*/
export interface UserForm {
id: number | undefined;
deptId: number;
username: string;
nickname: string;
password: string;
mobile: string;
email: string;
gender: number;
status: number;
remark: string;
roleIds: number[];
}
/**
* 用户导入表单类型声明
*/
export interface UserImportData {
deptId: number;
roleIds: number[];
}