axios + element 封装 - 拿去即用

news/2024/7/11 1:49:43 标签: ajax, vue.js, 前端, es6, javascript

      虽然本身axios本身就是一个完善的api,但是在工作环境中,为了使用起来更顺手,更好维护,所以一般我们会对axios进行二次封装。我的封装思路是把所有请求都放人一个文件夹,作为配置文件夹,这样的话好维护,然后根据配置去对发送的请求进行处理。代码上简单,有效。以下封装如有特殊需要,可以自己去添加或者修改使用。

interfaceConfig.js文件如下

export default {
  login: {
    url: 'login',
    method: 'post',
  },
   // 不配method 默认为get。{id} 会根据第三个请求参数进行替换
  getInfo:{
     url:"user/info/{id}"
  },
  uploadFild:{
     url:'download',
     method:'get'
  }
}

注意点:如果多人开发,建议按照模块建立多个js文件,最终在配置的index.js文件对这些配置合并。然后封装请求的文件引入index就好。可以解决多人协作开发配置接口冲突问题。

requir.js文件如下,包含的功能有:获取完整的请求路径、取消重复请求、根据环境修改baseUrl、自动去除字符窜首位空格、有contentType传参时,强制修改header内的content-type。

需要安装的依赖 base-64 和 js-cookie    yarn add js-cookie base-64 或者 npm i  js-cookie base-64,当然你有其他处理成base64和处理cookie的方法可以自行修改。 

javascript">import axios from "axios";
import interfaceConfig from "./interfaceConfig";
import Cookies from "js-cookie";
import router from "@/router";
import Base64 from "base-64";
import { ElMessage } from "element-plus";
let baseURL = "/api/v1";

const CancelToken = axios.CancelToken;
let requestList = [];

const instance = axios.create({
  // timeout: 5000, // 设置超时时间
  baseURL,
  withCredentials: true,
});

// 请求拦截器 发送一个请求之前
instance.interceptors.request.use(
  (config) => {
    const Authorization = Base64.decode(Cookies.get("cloud_serve") || "");
    config.headers = {
      Authorization,
      "Cache-Control": "no-cache",
    };
    // 添加请求到请求列表

    config.cancelToken = new CancelToken((c) => {
      // c 为取消请求方法,或者添加白名单允许发送请求
      if (requestList.includes(config.url)) {
        c();
      } else {
        requestList.push(config.url);
      }
    });

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

//添加响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 去除已请求成功的请求
    requestList = requestList.filter((item) => item !== response.config.url);
    return response || {};
  },
  async (error) => {
    if (error.code === "ERR_CANCELED") {
      console.log("请求已取消");
      return;
    }
    // 如果其他错误允许再次请求
    requestList = requestList.filter((item) => item !== error.config.url);
    if (
      error.code == "ECONNABORTED" &&
      error.message.indexOf("timeout") != -1
    ) {
      console.log("请求超时,请稍后重试");
      return;
    }

    if (error.response.status >= 400 && error.response.status < 500) {
      ElMessage.error(error.response.data.message);
    } else if (error.response.status === 401) {
      ElMessage.error(error.response.data.message || "401:权限失效");
      Cookies.remove("xxx");
      Cookies.remove("xxxxx");
      router.push("/login");
    } else if (error.response.status >= 500 && error.response.status < 600) {
      ElMessage.error(error.response.data.message || "5XX: 服务错误。");
      Cookies.remove("xxx");
      Cookies.remove("xxxxx");
      router.push("/login");
    }
    return error.response;
  }
);

// 递归处理参数两边空格 和拿掉无效字段
const handleParamsSpance = (params) => {
  if (Object.keys(params).length) {
    for (const key in params) {
      const type = Object.prototype.toString.call(params[key]).slice(8, -1);
      if (type === "Object") {
        handleParamsSpance(params[key]);
      } else if (type === "String" && params[key] !== "") {
        params[key] = params[key].trim();
      } else if (!params[key] && params[key] !== 0 && params[key] !== false) {
        delete params[key];
      }
    }
  }
  return params;
};

export function getquestUrl(interfaceConfigName, params = {}, id) {
  let url = interfaceConfig[interfaceConfigName].url;
  const method = interfaceConfig[interfaceConfigName].method || "get";
  if ((id && id !== "undefined") || id === 0) {
    if (url.indexOf("{id}") !== -1) {
      url = url.replace(/{id}/, id);
    } else {
      url = url + `/${id}`;
    }
  }

  // 清除参数首尾空格
  handleParamsSpance(params);
  if (method === "get" && Object.keys(params).length) {
    let str = "";
    for (const key in params) {
      str += `&${key}=${params[key]}`;
    }
    url = url + str.replace(/&/, "?");
  }
  return url;
}

// 返回完整地址,一般用通过cookies来下载或者上传
export function getUploadUrl(interfaceConfigName, params = {}, id) {
  const url = getquestUrl(interfaceConfigName, params, id);
  return location.origin + baseURL + "/" + url;
}

// 请求封装 第二个参数可以传 {}  request('接口名称',{},id)
export default function request(interfaceConfigName, params = {}, id) {
  const method = interfaceConfig[interfaceConfigName].method || "get";
  const url = getquestUrl(interfaceConfigName, params, id);
  return instance[method](url, params);
}

调用接口使用方式如下

javascript">// 引入 requestAPi 
import request from "@/httpRequest/request";

// 调用API
async submit(){
      const res = await request('getInfo', data, this.mealId);
      if (res.status === 200) {
        //...
      }

  }

下载文档或者图片调用,如果需要上传formDate格式的参数,注意需要在params里面传入对应的contentType:multipart/form-data  如上图。

补充:多人开发接口按模块划分,避免修改同一个文件冲突 


http://www.niftyadmin.cn/n/1162402.html

相关文章

element table 行高列宽拖拽调整

因为需求的不同&#xff0c;需要自己实现element表格拖拽调整列宽和行高&#xff0c;目前已实现&#xff0c;现记录了实现的方式。 实现说明&#xff1a;全部基于原生js,不依赖任何插件&#xff0c;可以直接使用。 实现思路&#xff1a;1.列宽的调整最终是通过调整如上图的col…

echarts 自定义事件交互方式修改

需求&#xff1a; 1.点击某个图例&#xff0c;图例高亮&#xff0c;只显示并选中当前的图例&#xff0c;同时展示数据。 再次点击这个高亮的图例&#xff0c;则全部图例选中 2.点击其他置灰图例&#xff0c;则此图例高亮&#xff0c;再次点击后&#xff0c;全部选中。 实现的方…

show-overflow-tooltip 在 safari 浏览器不生效

上面这种情况很大的可能性是因为 此列的 .cell.el-tooltip 元素的width属性被改变了&#xff0c;比如 width:auto。当然还有其他原因。如果实在找不到原因就在该页面修改权重为 .cell.el-tooltip的 width:100%。 如果实在找不到问题使用以下 scss 代码。 /deep/ .el-table__h…

Ant Design Charts 仪表盘配置属性结合案例详细说明

本次案例为仪表板&#xff0c;最终成品样式如下&#xff0c;案例种用到仪表盘分大部分属性&#xff0c;每个属性都注释说明作用。成品效果如下 使用方法如下 import { Gauge, G2 } from "ant-design/plots";const { registerShape, Util } G2; // 自定义指针 Shape…

批量文件夹上传实现,大量文件快速读取

前言本次开发对象云存储&#xff08;OSS&#xff09;运用到了文件上传&#xff0c;文件夹上传和拖拽上传这三个功能。开发基于VUE,但是其他框架的需要应用到的都可以应用。然后由于操作流程不一样需要自己去完成一个拖拽上传组件&#xff0c;但是网上查询的其他同学写的代码&am…

闭包之高阶函数中框架使用心得之--方法中自定义传参(解决elementUI的select选择器远程搜索功能自定义参数)

高阶函数中框架使用心得之--方法中自定义传参&#xff08;解决elementUI的select选择器远程搜索功能自定义参数&#xff09;前言主题问题所在原理解析先来说说什么是闭包结束前言 你好&#xff01; 我是一名前端攻城狮&#xff0c;这是第一次使用 Markdown编辑器 所展示的欢迎…

vue项目中使用generator函数

先来解释下什么叫generator函数* 语法上&#xff0c;可以把理解成&#xff0c;Generator 函数是一个状态机&#xff0c;封装了多个内部状态。 形式上&#xff0c;Generator 函数是一个普通函数。 整个Generator函数就是一个封装的异步任务&#xff0c;或者说是异步任务的容器…

vue项目中实现监听滚动条滚动事件并滚动到固定位置

vue项目中实现监听滚动条滚动事件并滚动到固定位置需求场景直接上代码THE LAST需求场景 项目结构&#xff1a;vue node.js webpack 滚动条滚动到某处的时候 tab就切换成当前位置的值并且点击tab还能滚动到想要的位置&#xff0c;大概就是锚点跳转的意思。 直接上代码 这里必…