Axios prêts à l'emploi et emballés soi-même

1. Demande

Dans le développement quotidien, nous utilisons souvent axios, alors comment encapsuler axios dans nos propres projets

2. Analyse

1. Installez axios

npm install axios

2. Créez un nouveau fichier ts pour encapsuler axios

Écrivez un fichier TS à la main : src\utils\request.ts, mon habitude est de le mettre dans le répertoire utils, le code source est le suivant

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 stocke les informations sur les jetons

Les informations de connexion de l'utilisateur sont stockées dans ma boutique et seul le jeton est utilisé lors de l'encapsulation d'axios, le code ci-dessous peut donc être utilisé comme référence

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", () => {
    
    
  // state
  const 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.xxx
          resolve();
        })
        .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. utiliser

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 de fichier.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;
}

おすすめ

転載: blog.csdn.net/qq_53810245/article/details/132315686