跳至主要內容

二次封装 axios

星火燎原@vxhly大约 4 分钟vuejsNode.jsWEBVue.jsJavaScript

前言

前后端分离的时候, 通常后端要求前端发送 JSON 请求, 而后端返回的格式也是 JSON 的, 这时候就需要一个中间插件 axios 上场, 本篇文章主要介绍在 vuejs 项目中是如何二次封装 axios 的, 本篇适宜阅读人群为有一些的 Vue.js 的开发基础经验。

关于 axios

介绍

Axios 是一个基于 promise 的 HTTP 库, 可以用在浏览器和 node.js 中。更多的介绍, 米娜桑上 GitHub 查看官方说明, axiosopen in new window, 这里不做过多的阐述

二次封装 axios

安装依赖

npm i axios
# or
yarn add axios

基础请求地址

一般来说一个项目至少对应一个后端 API 服务地址, 所以需要一个配置文件来存储这个后端 API 地址

src/config.js 中写入以下配置

export const baseHost = {
  API1: {
    dev_host: "http://[ip]:[port]/v[n]/api/", // 调试模式
    pro_host: "http://[ip]:[port]/v[n]/api/", // 线上模式
    file_host: "http://[ip]:[port]/v[n]/file/", // 文件存储前置 URL
  },
  API2: {
    dev_host: "http://[ip]:[port]/v[n]/api/", // 调试模式
    pro_host: "http://[ip]:[port]/v[n]/api/", // 线上模式
    file_host: "http://[ip]:[port]/v[n]/file/", // 文件存储前置 URL
  },
  // 还有其他的 API 往下加
};

src/API.vue 中添加后端的 API 地址, 此时添加的 API 地址无需在前面的 URL 部分写出来, 参考如下

<script>
export default {
  name: "API",

  user: {
    UserLogin: "/user/UserLogin", // GET 用户登录

    GetUserInfo: "/user/GetUserInfo", // GET 获取用户信息
  },

  logout: "/logout", // 登出账号
};
</script>

在你的 src/main.js 中注册这些 API 地址

import API from "./API.vue"; // 后端API接口地址

Vue.prototype.API = API; // 挂载到Vue实例上面

正式封装 axios

创建目录结构 src/libraries/axios , 并在这个目录下创建两个核心文件 featch.jshttp.js featch.js 文件主要编写 axios 的基础配置

import axios from "axios";

// 创建 axios 实例
const instance = axios.create({
  responseType: "json", // 返回数据类型
  // baseURL: serverURL, // 请求 URL
  timeout: 7000, // 超时时间
  maxContentLength: 2000, // 最大发包长度
  retry: 3, // 重试次数
  retryDelay: 3000, // 重试延时, 3秒重试一次
  shouldRetry: () => true, // 重试条件, 默认只要是错误都需要重试
});

// http request 拦截器
instance.interceptors.request.use(
  (config) => {
    // 在 headers 头上添加参数
    config.headers["Content-Type"] = "application/json;charset=UTF-8";
    const token = "";
    if (token) {
      config.headers["token"] = token;
    }

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

// http response 拦截器
instance.interceptors.response.use(
  (response) => {
    const { code } = response.data;
    switch (
      code
      // 这边可以对后端的一些状态码进行处理
    ) {
    }
  },
  (error) => {
    const { config } = error;
    // If config does not exist or the retry option is not set, reject
    if (!config || !config.retry) return Promise.reject(error);

    // Set the variable for keeping track of the retry count
    config.__retryCount = config.__retryCount || 0;

    // Check if we've maxed out the total number of retries
    if (config.__retryCount >= config.retry) {
      // Reject with the error
      Notification({
        title: "请求超时",
        message: "当前网络不佳, 请稍后刷新重试",
      });
      return Promise.reject(error);
    }

    // Increase the retry count
    config.__retryCount += 1;

    // Create new promise to handle exponential backoff
    var backoff = new Promise(function (resolve) {
      setTimeout(function () {
        resolve();
      }, config.retryDelay || 1);
    });

    // Return the promise in which recalls axios to retry the request
    return backoff.then(function () {
      return instance(config);
    });
  }
);

export default instance;

http.js 主要封装 GETPOSTPATCHDELETEPUT 方法

import featch from "./featch";
import { omitBy } from "lodash";
import { baseHost } from "@/config";
import axios from "axios";
let serverURL = "";
const env = process.env.NODE_ENV;

const getURL = (type) => {
  switch (env) {
    case "production":
      serverURL = baseHost[type].pro_host;
      break;
    case "development":
      serverURL = baseHost[type].dev_host;
      break;
    case "testing":
      serverURL = baseHost.test_host;
      break;
  }
  return serverURL;
};

/**
 * @method httpGet
 *
 * import { httpGet } from '@/libraries/axios/http'
 *
 * httpGet('', payload).then().catch()
 *
 * @param {String} url 请求地址
 * @param {Object} payload 请求参数
 * @param {String} type 设置 baseURL
 */

export const httpGet = async (url, payload, type = "API1") => {
  try {
    serverURL = getURL(type);
    axios.defaults.baseURL = serverURL;
    const response = await featch.get(`${url}`, {
      params: payload,
    });

    const result = response.data;
    return result;
  } catch (err) {
    throw new Error(err);
  }
};

/**
 * @method httpPost
 *
 * import { httpPost } from '@/libraries/axios/http'
 *
 * httpPost('', payload).then().catch()
 *
 * @param {String} url 请求地址
 * @param {Object} payload 请求参数
 */
export const httpPost = async (url, payload, type = "API1") => {
  try {
    serverURL = getURL(type);
    axios.defaults.baseURL = serverURL;
    const response = await featch.post(`${url}`, payload);

    const result = response.data;
    return result;
  } catch (err) {
    throw new Error(err);
  }
};

/**
 * @method httpPut
 *
 * import { httpPut } from '@/libraries/axios/http'
 *
 * httpPut('', payload).then().catch()
 *
 * @param {String} url 请求地址
 * @param {Object} payload 请求参数
 */
export const httpPut = async (url, payload, type = "API1") => {
  try {
    serverURL = getURL(type);
    axios.defaults.baseURL = serverURL;
    const response = await featch.put(`${url}`, payload);

    const result = response.data;
    return result;
  } catch (err) {
    throw new Error(err);
  }
};

/**
 * @method httpPatch
 *
 * import { httpPatch } from '@/libraries/axios/http'
 *
 * httpPatch('', payload).then().catch()
 *
 * @param {String} url 请求地址
 * @param {Object} payload 请求参数
 */
export const httpPatch = async (url, payload, type = "API1") => {
  try {
    serverURL = getURL(type);
    axios.defaults.baseURL = serverURL;
    const response = await featch.patch(`${url}`, payload);

    const result = response.data;
    return result;
  } catch (err) {
    throw new Error(err);
  }
};

/**
 * @method httpDelte
 *
 * import { httpDelte } from '@/libraries/axios/http'
 *
 * httpDelte('', payload).then().catch()
 *
 * @param {String} url 请求地址
 * @param {Object} payload 请求参数
 */
export const httpDelte = async (url, payload, type = "API1") => {
  try {
    serverURL = getURL(type);
    axios.defaults.baseURL = serverURL;
    const response = await featch.delete(`${url}`, {
      data: payload,
    });

    const result = response.data;
    return result;
  } catch (err) {
    throw new Error(err);
  }
};

使用案例

<script>
import { httpPost } from "@/libraries/axios/http";

export default {
  mounted() {
    const url = this.API.user.UserLogin;
    const payload = {
      userName: "admin",
      userPassword: "admin",
    };

    httpPost(url, payload).then((res) => {
      // 这里的 res 即是后端返回的数据结构
    });
  },
};
</script>
打赏
给作者赏一杯咖啡吧
您的支持将是我继续更新下去的动力
微信微信
支付宝支付宝