在vue3中封装ts请求方法

import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
import { ElMessageBox, ElLoading, ElMessage } from "element-plus";
import { LoadingInstance } from "element-plus/lib/components/loading/src/loading";
import router from "../router";
import { PRIFIX } from "../../public/config";

//消息提示
type Message =
  | boolean
  | {
      error: boolean | string;
      success: boolean | string;
    };
// loading
type Loading = boolean | LoadingInstance | string;

//请求参数
export interface RequestConfigOption
  extends AxiosRequestConfig,
    Record<string, any> {
  //请求类型
  requestType?: "form" | "json" | "file";
  //是否loading
  loading?: Loading;
  //是否消息提示
  message?: Message;
}

//处理提示参数
const processMessageOptions = (message: Message) => {
  if (typeof message == "boolean") {
    return { error: message, success: message };
  } else if (typeof message == "object") {
    return message;
  }
  return { error: false, success: false };
};
//ContentType 映射
const ContentTypeMap = {
  form: "application/x-www-form-urlencoded",
  file: "multipart/form-data",
  json: "application/json",
};
//处理header
const processHeader = (option: RequestConfigOption) => {
  const { requestType } = option;
  option.headers = option.headers || {};
  if (requestType && ContentTypeMap[requestType]) {
    option.headers["Content-Type"] = ContentTypeMap[requestType];
  }
  return option;
};

//处理loading参数
const processLoadingOptions = (loading: Loading) => {
  if (typeof loading == "boolean" && loading) {
    return { lock: true, text: "加载中" };
  } else if (typeof loading == "string") {
    return { lock: true, text: loading };
  } else if (typeof loading == "object") {
    return loading;
  }
  return false;
};

export const genHttp = (prefix: string) => {
  const instance = axios.create({
    baseURL: ("/" + prefix).replace(/\/\//g, "/"),
    // timeout: 120000,
    timeout: 1800000,
  });
  // 添加请求拦截器
  instance.interceptors.request.use(
    (config: RequestConfigOption) => {
      console.log("config", config);
      //处理头部
      processHeader(config);
      const urls = ["oauth/token"];
      const inUrl = urls.some((url) => config.url?.includes(url));
      if (!inUrl) {
        Object.assign(config.headers, {
          Authorization: localStorage.getItem("webtoken"),
          siteType: "web",
          userId: localStorage.getItem("webuser")
            ? JSON.parse(localStorage.getItem("webuser")).id
            : "",
          supplierCode: localStorage.getItem("supplierCode") || "",
        });
      } else {
        Object.assign(config.headers, {
          Authorization: config.Authorization,
          siteType: "web",
          userId: localStorage.getItem("webuser")
            ? JSON.parse(localStorage.getItem("webuser")).id
            : "",
          supplierCode: localStorage.getItem("supplierCode") || "",
        });
      }
      return config;
    },
    (error) => {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
  );

  // 添加响应拦截器
  instance.interceptors.response.use(
    async (response: AxiosResponse<BaseResponse<any>>) => {
      // 对响应数据做点什么
      const { status, data = {} as any } = response;
      if (status == 200) {
        interceptorFun(data);
        //兼容平台端的响应结构不规范
        if (!data.hasOwnProperty("success") || !data.hasOwnProperty("code")) {
          return Promise.resolve(response.data);
        }
        if (data.success) {
          return Promise.resolve(response.data);
        }
      } else if (status == 500) {
        ElMessage.error("系统异常");
      }
      return Promise.reject(data);
    },
    (error: AxiosError) => {
      if (error.response) {
        const { status, data = {} } = error.response;
        if (status == 401) {
          //客户端不给任何提示
          localStorage.setItem("tokenVaild", "");
          const haveTip = localStorage.getItem("haveTip") || "";
          if (!haveTip) {
            localStorage.setItem("haveTip", "1");
            ElMessageBox.alert("登录失效,前往登录页面", "提示", {
              confirmButtonText: "确定",
              showClose: false,
              callback: (action: any) => {
                router.push({ path: "/login" });
                localStorage.setItem("haveTip", "");
              },
            });
          }
          // router.push({name:'init', query: { redirect: encodeURIComponent(window.location.href) } });
          // router.push({path: "/login"});
          return Promise.reject({
            message: "登录失效",
          });
        }
        // 对响应错误做点什么
        return Promise.reject({
          ...data,
          message: data.message || data.error_description,
        });
      }
      // 对响应错误做点什么
      return Promise.reject({});
    }
  );
  //基础请求
  const request = (
    promise: Promise<BaseResponse<any>>,
    options?: RequestConfigOption
  ) => {
    options = options || {};
    //解析loading参数
    const loadingOptions = processLoadingOptions(options.loading as Loading);
    loadingOptions &&
      (options.$loading = ElLoading.service(loadingOptions as any));
    //解析message参数
    const messageOptions = processMessageOptions(options.message as Message);

    const getMessageStr = (value, defaultStr) => {
      return typeof value == "boolean" ? defaultStr : value;
    };

    return promise
      .then((res) => {
        const { message } = res;
        messageOptions.success &&
          ElMessage.success(
            getMessageStr(messageOptions.success, message || "操作成功")
          );
        return Promise.resolve(res);
      })
      .catch((res) => {
        const { message } = res;
        messageOptions.error &&
          ElMessage.error(
            getMessageStr(messageOptions.error, message || "操作失败")
          );
        return Promise.reject(res);
      })
      .finally(() => {
        options?.$loading?.close();
      });
  };

  const http = {
    get<T = any>(
      url: string,
      data?: Record<string, any>,
      options?: RequestConfigOption
    ): Promise<BaseResponse<T>> {
      return request(
        instance.get(url, { params: data || {}, ...options }),
        options
      );
    },
    post<T = any>(
      url: string,
      data?: Record<string, any>,
      options?: RequestConfigOption
    ): Promise<BaseResponse<T>> {
      return request(instance.post(url, data, { ...options }), options);
    },
    put<T = any>(
      url: string,
      data?: Record<string, any>,
      options?: RequestConfigOption
    ): Promise<BaseResponse<T>> {
      return request(instance.put(url, data, { ...options }), options);
    },
    delete<T = any>(
      url: string,
      data?: Record<string, any>,
      options?: RequestConfigOption
    ): Promise<BaseResponse<T>> {
      return request(
        instance.delete(url, {
          params: data || {},
          ...options,
        }),
        options
      );
    },
  };
  return http;
};

// 返回状态码拦截判断
const interceptorFun = (data: any) => {
  const status = data.status;
  if (status == 4000) {
    // 注册成功没有签合同
    router.push({ path: "/signingPage" });
  } else if (status == 4001) {
    // 合同审核中
    router.push({ path: "/onlineSign" });
  } else if (status == 4002) {
    // 合同审核不通过
    router.push({ path: "/onlineSign" });
  } else if (status == 4003) {
    // 合同审核通过,未支付
    router.push({ path: "/onlineSign" });
  } else if (status == 4004) {
    // 合同审核通过,支付审核中
    router.push({ path: "/onlinePay" });
  } else if (status == 4005) {
    // 合同审核通过,支付审核不通过
    router.push({ path: "/onlinePay" });
  } else if (status == 4006) {
    // 合同审核通过,支付审核通过
  }
};

//默认http
const http = genHttp(PRIFIX + "");
// const http = genHttp("/dsj-system");
//大厅
export const hallHttp = genHttp(PRIFIX + "/dsj-gpd-hall");
//云桌面
export const superCounterHttp = genHttp(PRIFIX + "/dsj-gpd-super-counter");
//事项
export const itemHttp = genHttp(PRIFIX + "/dsj-gpd-item");
//文件服务
export const fileHttp = genHttp(PRIFIX + "/dsj-file");
//combo服务
export const comboHttp = genHttp(PRIFIX + "/dsj-gpb-combo");
// dsj-business服务
export const businessHttp = genHttp("/dsj-business");

export default http;

外部写个通用方法把get请求参数拼接在URL

//api公共工具类
export default {
  getUrl(url: string, params: any) {
    if (params) {
      Object.keys(params).map((key, index) => {
        const pre = index == 0 ? "?" : "&";
        let val = params[key];
        if (val == null) val = "";
        url += `${pre}${key}=${val}`;
      });
    }
    return url;
  },
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UniApp是一个基于Vue.js的跨平台开发框架,可以同时开发iOS、Android、H5等多个平台的应用。Vue 3是Vue.js的最新版本,带来了许多新特性和改进。在UniApp使用Vue 3和TypeScript来封装请求可以按照以下步骤进行: 1. 安装依赖:在UniApp项目,首先需要安装axios库和@types/axios库,用于发送HTTP请求和提供TypeScript类型定义。 ```bash npm install axios @types/axios ``` 2. 创建请求封装文件:在项目的`src`目录下创建一个`api`文件夹,并在该文件夹下创建一个`request.ts`文件,用于封装请求相关的代码。 ```typescript import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; // 创建axios实例 const instance = axios.create({ baseURL: 'http://api.example.com', // 设置请求的基础URL timeout: 5000, // 设置请求超时时间 }); // 请求拦截器 instance.interceptors.request.use( (config: AxiosRequestConfig) => { // 在发送请求之前做一些处理,例如添加token等 return config; }, (error) => { // 处理请求错误 return Promise.reject(error); } ); // 响应拦截器 instance.interceptors.response.use( (response: AxiosResponse) => { // 对响应数据进行处理,例如统一处理错误码等 return response.data; }, (error) => { // 处理响应错误 return Promise.reject(error); } ); // 封装GET请求 export function get(url: string, params?: any): Promise<any> { return instance.get(url, { params }); } // 封装POST请求 export function post(url: string, data?: any): Promise<any> { return instance.post(url, data); } // 其他请求方法封装,例如PUT、DELETE等 ``` 3. 使用请求封装:在需要发送请求的地方,引入`request.ts`文件,并调用相应的请求方法。 ```typescript import { get, post } from '@/api/request'; // 发送GET请求 get('/user/info', { id: 1 }) .then((response) => { console.log(response); }) .catch((error) => { console.error(error); }); // 发送POST请求 post('/user/login', { username: 'admin', password: '123456' }) .then((response) => { console.log(response); }) .catch((error) => { console.error(error); }); // 其他请求方法的使用,例如PUT、DELETE等 ``` 以上就是在UniApp使用Vue 3和TypeScript封装请求的基本步骤。你可以根据实际需求进行进一步的封装和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值