Vue功能篇 - 3.封裝axios請求庫

情繫半生e發表於2020-11-18

Vue封裝axios請求庫

import axios from 'axios';
import {
  Message,
  Loading
} from 'element-ui';
import router from '../router';
import _ from 'lodash';
import qs from 'qs';

const http = axios.create({
  baseURL: process.env.API_HOST, //設定請求的base url
  timeout: 300000, //超時時長5分鐘,
  crossDomain: true
});

http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8;multipart/form-data'
http.defaults.paramsSerializer = (params) => {
  return qs.stringify(params, {
    arrayFormat: 'brackets'
  });
}
//loading物件
let loading;

//當前正在請求的數量
let needLoadingRequestCount = 0;

//顯示loading
function showLoading(target) {
  // 後面這個判斷很重要,因為關閉時加了抖動,此時loading物件可能還存在,
  // 但needLoadingRequestCount已經變成0.避免這種情況下會重新建立個loading
  if (needLoadingRequestCount === 0 && !loading) {
    loading = Loading.service({
      lock: true,
      text: "拼命載入中····",
      background: 'rgba(255, 255, 255, 0.5)',
      target: target || "body"
    });
  }
  needLoadingRequestCount++;
}

//隱藏loading
function hideLoading() {
  needLoadingRequestCount--;
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做個保護
  if (needLoadingRequestCount === 0) {
    //關閉loading
    toHideLoading();
  }
}

//防抖:將 300ms 間隔內的關閉 loading 便合併為一次。防止連續請求時, loading閃爍的問題。
var toHideLoading = _.debounce(() => {
  if (loading != null) {
    loading.close();
  }
  loading = null;
}, 300);

//新增請求攔截器
http.interceptors.request.use(config => {
  //判斷當前請求是否設定了不顯示Loading
  if (config.headers.showLoading !== false) {
    showLoading(config.headers.loadingTarget);
  }
  config.url = decodeURI(encodeURI(config.url).replace('%E2%80%8B',""))
  if (config.method === 'post') {
    config.data = qs.stringify(config.data);
  }
  // const token = store.state.token
  const token = sessionStorage.token;
  if (token&&config.method==='post') {
    config.headers.common["Authorization"] = token;
  }
  return config;
}, err => {
  //判斷當前請求是否設定了不顯示Loading
  if (config.headers.showLoading !== false) {
    hideLoading();
  }
  console.log('555555555555');
  Message.error('請求超時!');
  return Promise.resolve(err);
});

//響應攔截器
http.interceptors.response.use(
  response => {
    //判斷當前請求是否設定了不顯示Loading(不顯示自然無需隱藏)
    if (response.config.headers.showLoading !== false) {
      hideLoading();
    }
    if (response.status === 200) {
      if (response.data && response.data.state === -1 && response.data.msg == '登陸過期,請重新登陸') {
        Message.error("登入過期,請重新登入");
        sessionStorage.removeItem('loginName');
        router.push({
          name: 'login'
        });
      }
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
    return response;
  },
  error => {
    //判斷當前請求是否設定了不顯示Loading(不顯示自然無需隱藏)
    // if (error.config.headers.showLoading !== false) {
      hideLoading();
    // }
    //攔截錯誤
    if (error.response && error.response.data && error.response.data.message) {
      var jsonObj = JSON.parse(error.response.data.message);
      Message.error(jsonObj.message);
    } else {
      Message.error("網路請求錯誤");
    }
    
    // if(error.response && error.response.data && error.response.data.message) {
    //   var jsonObj = JSON.parse(error.response.data.message);
    //   Message.error(jsonObj.message);
    // }else{
    //   Message.error(error.message);
    // }//     if (error.response.status) {
    //       switch (error.response.status) {
    //         // 401: 未登入
    //         // 未登入則跳轉登入頁面,並攜帶當前頁面的路徑
    //         // 在登入成功後返回當前頁面,這一步需要在登入頁操作。
    //         case 401:
    //           router.replace({
    //             path: '/login',
    //             query: { redirect: router.currentRoute.fullPath }
    //           })
    //           break
    //         // 403 token過期
    //         // 登入過期對使用者進行提示
    //         // 清除本地token和清空vuex中token物件
    //         // 跳轉登入頁面
    //         case 403:
    //           Toast({
    //             message: '登入過期,請重新登入',
    //             duration: 1000,
    //             forbidClick: true
    //           })
    //           // 清除token
    //           localStorage.removeItem('token')
    //           store.commit('loginSuccess', null)
    //           // 跳轉登入頁面,並將要瀏覽的頁面fullPath傳過去,登入成功後跳轉需要訪問的頁面
    //           setTimeout(() => {
    //             router.replace({
    //               path: '/login',
    //               query: {
    //                 redirect: router.currentRoute.fullPath
    //               }
    //             })
    //           }, 1000)
    //           break
    //         // 404請求不存在
    //         case 404:
    //           Toast({
    //             message: '網路請求不存在',
    //             duration: 1500,
    //             forbidClick: true
    //           })
    //           break
    //         // 其他錯誤,直接丟擲錯誤提示
    //         default:
    //           Toast({
    //             message: error.response.data.message,
    //             duration: 1500,
    //             forbidClick: true
    //           })
    //       }
    //       return Promise.reject(error.response)
    //     }
    return Promise.reject(error);
  }
);

export default http;

Api引入式呼叫

import request from "@/http/httpload.js"
	export default{
		getData(data){
		return request({
			url:"/api/xxx",
			method:"post",
			data:data
		})
	}
}

相關文章