vue封装axios

1 篇文章 0 订阅

在VUE开发过程中免不了使用axios,官方的axios使用在项目中使用起来还是不怎么方便的,例如对于异步的处理并不完美、请求参数的加密等。

话不多说,直接上代码:

import axios from "axios";
import store from "store/";
import qs from "qs"; // 序列化传参,以&符号连接
import md5 from "md5"; // 加密方法

import {
  AUTH_FAIL
} from "@/store/modules/user/constant";


export const CancelToken = axios.CancelToken;

// 创建axios对象
const instance = axios.create();
instance.defaults.withCredentials = true; // 跨域请求时是否需要使用凭证

// instance.defaults.timeout = 20000; // 指定请求超时的毫秒数(0 表示无超时时间)

function get(url, postedData = {}, otherOptions = {}) {
  return networkCall(instance.get(url, postedData, otherOptions));
}


function post(url, postedData = {}, otherOptions = {}) {
  const { isLogin } = postedData;

  delete postedData.isLogin;

  otherOptions.headers = paramEncrypt(postedData);

  return networkCall(instance.post(url, postedData, otherOptions), isLogin);
}

function postForm(url, postedData = {}, otherOptions = {}) {
  return networkCall(instance.post(url, qs.stringify(postedData), otherOptions));
}

function put(url, postedData = {}, otherOptions = {}) {
  return networkCall(instance.put(url, qs.stringify(postedData), otherOptions));
}

function del(url, postedData = {}, otherOptions = {}) {
  return networkCall(instance.delete(url, postedData, otherOptions));
}

/** 参数加密 */
function paramEncrypt(params = {}) {
  const timestamp = new Date().getTime();
  
  let sign = md5(`zh${JSON.stringify(params)}2019${timestamp}`);

  let res = {
    timestamp,
    sign
  };
  
  const token = localStorage.getItem("requestToken");

  if (token) {
    res.token = token;
  }

  return res;
}

async function download(url, postedData = {}, otherOptions = {}) {
  try {
    otherOptions.headers = paramEncrypt(postedData);

    const res = await instance.post(url, postedData, {
      responseType: "blob", // 服务器响应的数据类型
      ...otherOptions
    });

    const { data, headers, code, reason } = res;

    if (!data) return;

    if (code && code === "-1") {
      return Promise.reject({
        code,
        reason
      });
    } else if (code && +code === 403) {
      store.dispatch({
        type: AUTH_FAIL,
        reason
      });
    } else { // 下载成功
      const fileName = decodeURI(headers["content-disposition"].split("filename=")[1]);
      const fileUrl = window.URL.createObjectURL(new Blob([data]));

      let link = document.createElement("a");

      link.style.display = "none";
      link.href = fileUrl;
      link.setAttribute("download", fileName);

      document.body.appendChild(link);
      
      link.click();

      document.body.removeChild(link);
      window.URL.revokeObjectURL(fileUrl);
    }
  } 
  catch (error) {
    console.error("request exception -> error", error);

    return Promise.reject(error);
  }
}

async function all(axiosPromiseArray) {
  try {
    return await Promise.all(axiosPromiseArray);
  } catch (error) {
    console.info("axios all error", error);
    return Promise.reject(error);
  }
}

async function networkCall(axiosPromise, isLogin) {
  try {
    const response = await axiosPromise;
    const resData = await response.data;
    const { code, reason } = resData;
    
    if (+code === 0) { // 请求成功
      if (isLogin) {
        localStorage.setItem("requestToken", resData.data.token);
      }

      return resData.data;
    } 
    else if (+code === 403) { // 验证失败
      store.dispatch({
        type: AUTH_FAIL,
        reason
      });
    } else { // 请求失败
      console.error("request fail -> code: ", code);
      
      return Promise.reject({
        code,
        reason
      });
    }

  } catch (error) { // 请求异常  status !== 200
    console.error("request exception -> error", error);

    globalAxiosErrorHandler(error);

    return Promise.reject(error);
  }
}

function globalAxiosErrorHandler(error) {
  const host = window.location.origin;
  const { status, statusText } = error.response;
  const { method, url } = error.config;

  const timestamp = Date.now();

  // todos: different dealings;
  console.error(`${dateFormat(timestamp)}  ${method.toUpperCase()}: ${host}${url}  ${status} (${statusText})`);
}

function dateFormat(date, fmt = "yyyy-MM-dd hh:mm:ss") {
  if (!date) {
    throw new Error(`argument 'date' is required`);
  }
  if (!(date instanceof Date)) {
    date = new Date(date);
  }
  const o = {
    "M+": date.getMonth() + 1, // 月份
    "d+": date.getDate(), // 日
    "h+": date.getHours(), // 小时
    "m+": date.getMinutes(), // 分
    "s+": date.getSeconds(), // 秒
    "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
    "S": date.getMilliseconds() // 毫秒
  };

  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  }

  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    }
  }
  return fmt;
}

export default {
  delete: del,
  del,
  get,
  post,
  postForm,
  put,
  all,
  download,
  CancelToken
};

封装好之后可以这样调用:


import axios from "@/modules/axios";

export default {
  components: {},

  data() {
    return {
      loading: false,
      data1: [],
      data2: []
    };
  },

  computed: {
    
  },

  watch: {
    
  },

  async mounted() {
    this.loading = true;

    await this.getData1();
    await this.getData2();

    this.loading = false;
  },

  methods: {
    async getData1(){
        try {

            let data = await axios.post("/api/formData/list", {page:1,pageSize:50});
            this.data1 = data;

        } catch (err) {
            err.reason && this.$$message(err.reason);
        }
    },
    async getData2(){
        try {

            let data = await axios.get("/api/formData/class", {id:1});
            this.data2= data;

        } catch (err) {
            err.reason && this.$$message(err.reason);
        }
    },
    async handleDownload() {
      try {

        await axios.download(`/api/formData/downloadForm`,{page:1,pageSize:100});

      } catch (err) {
        err.reason && this.$$message(err.reason);
      }
    },
  }
}

 

其中关于CancelToken的用法我并没有加上,如果想要优化请求的性能的话请参考这篇文章:

https://www.jianshu.com/p/42d1c58e785e

以上内容仅供参考,如果错漏,请及时指出,感激不尽!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专业前端小白

写了这么久文章,1分钱都没收到

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值