文章目錄
- 一、需求
- 二、分析
- 1. 安裝axios
- 2. 新建一個 ts 文件,封裝 axios
- 3. store 存放 token 信息
- 4. 使用
- 5. 文件 type.js
一、需求
在日常開發中,我們會經常用到 axios ,那么如何在自己的項目中自己封裝 axios
二、分析
1. 安裝axios
npm install axios
2. 新建一個 ts 文件,封裝 axios
手寫一個TS文件: src\utils\request.ts
,我的習慣把它放在 utils 目錄下,源碼如下
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 = userStore.token;}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;}// 響應數據為二進制流處理(Excel導出)if (response.data instanceof ArrayBuffer) {return response;}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();window.location.href = "/";});} else {ElMessage.error(msg || "系統出錯");}}return Promise.reject(error.message);}
);// 導出 axios 實例
export default service;
3. store 存放 token 信息
我的 store 中存放了用戶的登錄信息,在封裝 axios 時只用到了 token,因此下方代碼可做參考
import { defineStore } from "pinia";import { loginApi, logoutApi } from "@/api/auth";
import { getUserInfo } from "@/api/user";
import { resetRouter } from "@/router";
import { store } from "@/store";import { LoginData } from "@/api/auth/types";
import { UserInfo } from "@/api/user/types";import { useStorage } from "@vueuse/core";export const useUserStore = defineStore("user", () => {// stateconst userId = ref();const token = useStorage("accessToken", "");const nickname = ref("");const avatar = ref("");const roles = ref<Array<string>>([]); // 用戶角色編碼集合 → 判斷路由權限const perms = ref<Array<string>>([]); // 用戶權限編碼集合 → 判斷按鈕權限/*** 登錄調用** @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.xxxresolve();}).catch((error) => {reject(error);});});}// 獲取信息(用戶昵稱、頭像、角色集合、權限集合)function getInfo() {return new Promise<UserInfo>((resolve, reject) => {getUserInfo().then(({ data }) => {if (!data) {return reject("Verification failed, please Login again.");}if (!data.roles || data.roles.length <= 0) {reject("getUserInfo: roles must be a non-null array!");}userId.value = data.userId;nickname.value = data.nickname;avatar.value = data.avatar;roles.value = data.roles;perms.value = data.perms;resolve(data);}).catch((error) => {reject(error);});});}// 注銷function logout() {return new Promise<void>((resolve, reject) => {logoutApi().then(() => {resetRouter();resetToken();location.reload(); // 清空路由resolve();}).catch((error) => {reject(error);});});}// 重置function resetToken() {token.value = "";nickname.value = "";avatar.value = "";roles.value = [];perms.value = [];}return {token,nickname,avatar,roles,perms,login,getInfo,logout,resetToken,/*** 當前登錄用戶ID*/userId,};
});// 非setup
export function useUserStoreHook() {return useUserStore(store);
}
4. 使用
import request from "@/utils/request";
import { AxiosPromise } from "axios";
import { UserForm, UserInfo, UserQuery } from "./types";/*** 登錄成功后獲取用戶信息(昵稱、頭像、權限集合和角色集合)*/
export function getUserInfo(): AxiosPromise<UserInfo> {return request({url: "/api/v1/users/me",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 ids*/
export function deleteUsers(ids: string) {return request({url: "/api/v1/users/" + ids,method: "delete",});
}
/*** 下載用戶導入模板** @returns*/
export function downloadTemplateApi() {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, file: File) {const formData = new FormData();formData.append("file", file);return request({url: "/api/v1/users/_import",method: "post",params: { deptId: deptId },data: formData,headers: {"Content-Type": "multipart/form-data",},});
}
5. 文件 type.js
/*** 用戶查詢對象類型*/
export interface UserQuery {keywords?: string;status?: number;deptId?: number;
}/*** 登錄用戶信息*/
export interface UserInfo {userId: number;nickname: string;avatar: string;roles: string[];perms: string[];
}/*** 用戶表單類型*/
export interface UserForm {/*** 用戶頭像*/avatar?: string;/*** 部門ID*/deptId?: number;/*** 郵箱*/email?: string;/*** 性別*/gender?: number;/*** 用戶ID*/id?: number;mobile?: string;/*** 昵稱*/nickname?: string;/*** 角色ID集合*/roleIds?: number[];/*** 用戶狀態(1:正常;0:禁用)*/status?: number;/*** 用戶名*/username?: string;
}