Vue 中 axios 的封装详解

一、创建 Axios 实例

/**
 * @fileOverview 封装 axios 请求模块
 */

import axios from "axios";

// 创建 axios 实例
const axiosInstance = axios.create({
  // 设置基础请求路径
  baseURL: "https://api.example.com",
  // 设置请求超时时间
  timeout: 5000,
  // 设置默认请求头
  headers: {
    "Content-Type": "application/json"
  }
});

二、配置请求拦截器

/**
 * 配置请求拦截器
 * 在请求发送前可以做统一处理,比如添加认证 token
 */
axiosInstance.interceptors.request.use(
  (config) => {
    // 获取存储在本地的认证 token
    const token = localStorage.getItem("authToken");
    if (token) {
      // 如果存在 token,添加到请求头中
      config.headers.Authorization = `Bearer ${token}`;
    }
    // 返回配置好的请求
    return config;
  },
  (error) => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

三、配置响应拦截器

/**
 * 配置响应拦截器
 * 在收到响应后可以做统一处理,比如处理错误信息
 */
axiosInstance.interceptors.response.use(
  (response) => {
    // 如果响应数据存在,返回响应数据,否则返回整个响应对象
    return response.data || response;
  },
  (error) => {
    // 获取错误的响应信息
    const { response } = error;
    if (response) {
      // 如果有响应,输出错误状态码和状态信息
      console.error(`Error ${response.status}: ${response.statusText}`);
    } else {
      // 如果没有响应,输出错误信息
      console.error(`Error: ${error.message}`);
    }
    // 返回拒绝的错误 Promise
    return Promise.reject(error);
  }
);

四、封装 API 请求类

/**
 * 封装 API 请求类
 */
class Api {
  /**
   * 发送 GET 请求
   * @param {string} url 请求路径
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static get(url, config = {}) {
    return axiosInstance.get(url, config);
  }

  /**
   * 发送 POST 请求
   * @param {string} url 请求路径
   * @param {object} data 请求数据
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static post(url, data = {}, config = {}) {
    return axiosInstance.post(url, data, config);
  }

  /**
   * 发送 PUT 请求
   * @param {string} url 请求路径
   * @param {object} data 请求数据
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static put(url, data = {}, config = {}) {
    return axiosInstance.put(url, data, config);
  }

  /**
   * 发送 DELETE 请求
   * @param {string} url 请求路径
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static delete(url, config = {}) {
    return axiosInstance.delete(url, config);
  }
}

五、封装为模块

// 导出封装好的 API 类
export default Api;

六、在项目中使用封装后的 Axios

// 在项目中使用封装后的 Axios
import Api from "@/axios";

Api.get("/users")
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

七、封装 Api 类

/**
 * @fileOverview 封装 axios 请求模块
 */

import axios from "axios";
import defaultConfig from './config.js'; // 默认配置

/**
 * 创建 API 请求类
 */
class Api {
  /**
   * 创建 API 实例
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static _createApi(config) {
    // 创建 axios 实例
    const instance = axios.create({
      ...defaultConfig,
    });
    // 设置请求拦截器
    Api.setRequestInterceptor(instance);
    // 设置响应拦截器
    Api.setResponseInterceptor(instance);
    // 返回配置好的请求实例
    return instance(config);
  }

  /**
   * 发送请求
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static request(config = {}) {
    return Api._createApi(config);
  }

  /**
   * 发送 GET 请求
   * @param {string} url 请求路径
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static get(url, config = {}) {
    return Api._createApi({
      url,
      method: 'GET',
      ...config
    });
  }

  /**
   * 发送 POST 请求
   * @param {string} url 请求路径
   * @param {object} data 请求数据
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static post(url, data = {}, config = {}) {
    return Api._createApi({
      url,
      data,
      method: 'POST',
      ...config
    });
  }

  /**
   * 发送 PUT 请求
   * @param {string} url 请求路径
   * @param {object} data 请求数据
   * @param {object} config 请求配置
   * @returns {Promise} 请求结果
   */
  static put(url, data = {}, config = {}) {
    return Api._createApi({
      url,
      data,
      method: 'PUT',
      ...config
    });
  }
}

// 导出 Api 类
export default Api;

八、请求参数处理

function transformRequestConfig(params) {
  const config = {
    url: params.request.url || '',
    method: params.request.method,
    skipErrorHandler: params.skipErrorHandler,
    request: params.request,
  };
  // 配置处理
  return config;
}

九、处理业务错误和通用错误

static handleBusinessError = (errCode, errMsg) => {
  const bErrMap = {
    '10000': {
      msg: '审核中',
      dangerouslyUseHTMLString: true,
    },
  };

  const defaultError = {
    msg: errMsg,
    dangerouslyUseHTMLString: true,
  };

  const error = bErrMap[errCode] || defaultError;

  const options = {
    title: error.title || '提示信息',
    confirmButtonText: '确定',
    dangerouslyUseHTMLString: error.dangerouslyUseHTMLString,
  };

  const { title, ...restOptions } = options;
  error.msg && app.$alert(error.msg, title, restOptions);

  return bErrMap.hasOwnProperty(errCode);
};

static handleGeneralError = (errCode, errMsg) => {
  const gErrMap = {
    '-1': {
      msg: '系统错误,请联系网站开发组'
    },
    '-2': {
      handler: () => { }
    },
    '-3': {
      msg: '您还没有该操作权限',
    },
    '-4': {
      msg: '参数错误:' + errMsg,
      dangerouslyUseHTMLString: true,
    },
    '-5': {
      hasBusinessError: true
    },
    '-6': {
      title: '系统错误',
      msg: '服务配置错误'
    },
  };

  const defaultError = {
    msg: '未知错误',
  };

  const error = gErrMap[errCode] || defaultError;

  const options = {
    title: error.title || '提示信息',
    confirmButtonText: '确定',
    dangerouslyUseHTMLString: error.dangerouslyUseHTMLString,
  };
  const { title, ...restOptions } = options;
  if (error.hasBusinessError) return false;
  error.msg && app.$alert(error.msg, title, restOptions);
  error.handler && error.handler();
  return true;
};

十、封装为模块并使用

// src/axios.js
import axios from "axios";
import defaultConfig from './config.js'; // 默认配置

// 创建 axios 实例
const axiosInstance = axios.create({
  ...defaultConfig,
});

// 设置请求拦截器
Api.setRequestInterceptor(axiosInstance);

// 设置响应拦截器
Api.setResponseInterceptor(axiosInstance);

// 导出封装好的 API 类
export default Api;

// 在项目中使用封装后的 Axios
import Api from "@/axios";

Api.get("/users")
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

通过以上步骤,我们可以对 axios 进行封装,实现统一的请求拦截和响应处理,从而提升代码的可维护性和用户体验。在实际开发中,可以根据具体需求进一步扩展封装逻辑,例如添加日志记录、重试机制等。

你可能感兴趣的:(Vue.js,vue.js,前端,javascript)