axios配合element-ui封装

以下是个人在请求调用接口时再次封装的axios的plugins,以便项目中使用
import Vue from 'vue';
import axios from 'axios';
import Cookies from 'js-cookie';
import qs from "qs";
import {
  Loading
} from 'element-ui';

import HttpCodeHandle from './httpcodehandle';
import utils from '@/utils/utils';
import storagekeys from '@/utils/configs/storagekeys';

window.loadinginstace = null; // 控制loading
let loadingNum = 0; // 调用loading次数

let _config = {
  baseURL: process.env.VUE_APP_BASE_API || "",
  timeout: 180 * 1000, // Timeout
  withCredentials: true, // Check cross-site Access-Control
  headers: {
    'Content-Type': 'application/json'
  },
  responseType: 'json',
  // 请求前对数据进行处理
  transformRequest: [function (data) {
    if (data && utils.isObject(data)) {
      // 这里可对当前数据进行处理
    }
    // 判断数据类型 是否是 FormData 数据类型  用于上传
    if (data && data.get && (typeof data.get === "function") && data.get("isFormData")) {
      return data;
    }
    return JSON.stringify(data);
  }],
  paramsSerializer: function (params) {
    return qs.stringify(params, {
      indices: false
    });
  }
};

const _axios = axios.create(_config);
_axios.interceptors.request.use(
  function (config) {
    // 在发送前做些什么
    if (loadingNum === 0) {
      // 若是不需要全局loading展示,则直接使用hideLoading来配置,hideLoading为自定义配置
      if (config.hideLoading) {
        window.loadinginstace = null;
        delete config.hideLoading;
      } else {
        window.loadinginstace = Loading.service({
          // 自定义loading区域,若没有isLoadingRegionPart则默认全屏,main-body这个id为局部id
          target: config.isLoadingRegionPart ? '#main-body' : '#app',
          fullscreen: true,
          // 自定义loading文案,若没有则默认不展示
          text: config.loadingText ? config.loadingText : "",
          background: 'rgba(0, 0, 0, 0.2)'
        });
      }
      // 最后删除这两个自定义的内容
      if (config.isLoadingRegionPart) {
        delete config.isLoadingRegionPart;
      }
      if (config.loadingText) {
        delete config.loadingText
      }
    }

    loadingNum += 1;
    // 新增token
    let usertoken = Cookies.get(storagekeys.cookies.usertoken);
    if (usertoken) {
      config.headers.Authorization = usertoken;
    } else if (config.headers.Authorization) {
      delete config.headers.Authorization;
    }
    return config;
  },
  function (error) {
    // 请求错误时做些什么
    loadingNum -= 1;
    if (loadingNum === 0) {
      window.loadinginstace && window.loadinginstace.close();
    }
    return Promise.reject(error);
  }
);
// 处理登录请求token
function handleAuthorizationCooike(resData) {
  if (resData && resData.headers && resData.headers.authorization) {
    Cookies.set(storagekeys.cookies.usertoken, resData.headers.authorization, {
      expires: 1
    });
    return true;
  }
  return false;
}

// 添加响应拦截器
_axios.interceptors.response.use(
  function (response) {
    loadingNum -= 1;
    if (loadingNum === 0) {
      window.loadinginstace && window.loadinginstace.close();
    }
    // 处理正确数据返回弹框
    HttpCodeHandle(response, true);
    // 判断是否是登录接口调用
    if (handleAuthorizationCooike(response)) {
      return true;
    }
    return response.data;
  },
  function (error) {
    // Do something with response error
    loadingNum -= 1;
    if (loadingNum === 0) {
      window.loadinginstace && window.loadinginstace.close();
    }
    // 进行处理对应错误弹框提示
    HttpCodeHandle(error, false);
    return Promise.reject(error);
  }
);

Plugin.install = function (Vue, options) {
  Vue.axios = _axios;
  window.axios = _axios;
  Object.defineProperties(Vue.prototype, {
    axios: {
      get() {
        return _axios;
      }
    },
    $axios: {
      get() {
        return _axios;
      }
    }
  });
};

Vue.use(Plugin);

export default Plugin;

以上代码简单解释下,handleAuthorizationCooike这个方法是判断登录,然后进行存储登录后返回的token,因为token并不在data里边,而是在header中;

loadingNum这个计数判断是因为如果多次请求,你会发现在页面中多次loading,这是记录一下,若已经有了loading,那么就不需要再次```loading````了

qs.stringify,这个方法会引出另外一个问题:对于get请求,如果传递数组,在请求接口后边有哪几种方式拼接参数?接口又是如何处理的?

这里举两个例子,qs正好处理这些拼接方式 ,可以查看qs文档,不同的方式解析以便配合接口对应不同的组装方法

  1. 比如接口/a传递数据b:["hello","world"],在我上方那块代码中处理就是/a?b=hello&b=world,而接口那边就需要把b组装好还原成之前的数据了
  2. 第二种就是/a?b[0]=hello&b[1]=world
posted @ 2019-10-16 09:59  sixth-rhapsody  阅读(726)  评论(0)    收藏  举报