關於axios的一些封裝

關於Axios的封裝css

爲什麼須要在封裝

應用場景,項目中涉及100個AJAX請求,其中:vue

1.其中60個須要在請求頭header設置token headers: {token: token}用於權限校驗;ios

2.其中20個爲上傳EXCEL文件須要在請求頭中設置Content-Type;vuex

headers: {
      'Content-Type': `multipart/form-data; boundary=${data._boundary}`
}

上面說的 一、二、3能夠在全局request攔截中進行處理,可是代價極大,須要爲這100個接口都作判斷再作相應處理... ;固然也能夠不用全局攔截,爲每一個接口都單獨定義,我相信有很多同窗還是這樣處理的,可是只要有改動,例如如今我要求全部的請求頭都新增一個參數,那就只能一個一個接口的改.....這不是咱們想要的結果,因此 咱們須要對AJAX再封裝!AJAX再封裝!AJAX再封裝!,由於至關重要,因此要多說幾遍....element-ui

  1. ③最後20個請求用來獲取文件流,須要指定接受類型responseType: 'blob'json

  1. 須要對全局發起request進行攔截並作異步處理強調:是異步處理);axios

  1. 若是你的項目已經作到一半,如今後端要加上token權限作認證;後端

封裝實現

封裝其實很簡單,就是對原來真正的AJAX套一個殼這個殼就是一個函數! 在這個函數裏都幹了些什麼見不得人事呢?幹什麼均可以,上面說的一、 二、 三、 四、 5均可以在這裏悄悄的進行,那對原來的AJAX鏈式調用有影響嗎?答案是確定的:沒有影響。 先來看看我在代碼裏調用的AJAX:api

_initEditParams () {
  this.$axios('Common/Permission/Get', {Id}).then(res => {
  ....
  ....
  })
},

this.$axios能夠直接調用是由於這裏把請求方法之類的配置項全放在封裝裏面進行了。服務器

這裏也是經過Vue.prototype.$axios = axios添加到vue全局實例的,但這裏添加的axios不是直接引入的axios插件,而是一個方法

import {axios} from './utils/common'
Vue.prototype.$axios = axios

固然。也能夠不用添加到全局實例裏面,能夠在組件中經過import語法引入使用。固然是項目裏大量使用的封裝方法直接使用Vue.prototype添加到vue實例。接下來咱們看看axios方法都作了些啥

import Axios from 'axios'
import Store from '../vuex'

/*********************************
** Fn: axios
** Intro: 公用封裝的axios 已在main.js中進行 $axios代理
** Intro: Store.state.permission.constUrl 爲公用的接口前綴地址
** Intro: url 方法接受參數 爲定義的 接口地址後綴
** Intro: data 方法接受參數 爲定義的參數
** Author: zyx
*********************************/

export function axios (url, data) {
return new Promise((resolve, reject) => {
  Axios({
    url: `${Store.state.permission.constUrl}${url}`,
    method: 'post',
    data: data,
    headers: {
      token: Store.state.permission.token
    }
  }).then(res => {
    resolve(res)
  }).catch(err => {
    reject(err)
  })
})
}

Axios的封裝

在目錄下新建一個Axios文件夾,在文件夾下新建文件axios.js,文件內容:

import Axios from "axios";
import qs from "qs";
import router from "@/router/router.js";
// import { Message } from "element-ui";

/****** 建立axios實例 ******/
const Service = Axios.create({
 baseURL: process.env.BASE_URL, // api的base_url
 timeout: 10000, // 請求超時時間
 responseType: "json",
 withCredentials: true, // 是否容許帶cookie這些
 headers: {
   //   "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
   "Content-Type": "application/json;charset=utf-8"
}
});

// 設置請求攔截器
Service.interceptors.request.use(config => {
   // 在發送請求以前作某件事
   if (config.method === "post") {
     // 序列化
     // config.data = qs.stringify(config.data);
     // config.data = JSON.stringify(config.data);
     // 舒適提示,如果公司的提交能直接接受json 格式,能夠不用 qs 來序列化的
  }
   // 如果有作鑑權token , 就給頭部帶上token
   // 如果須要跨站點,存放到 cookie 會好一點,限制也沒那麼多,有些瀏覽環境限制了 localstorage 的使用
   // if (localStorage.token) {
   //   config.headers.Authorization = localStorage.token;
   // }
   return config;
},
 error => {
   // error 的回調信息,看公司的定義
   Message({
     showClose: true,
     message: error,
     type: "warning"
  });
   return Promise.reject(error);
})

// 響應攔截 http 請求回來的一些狀態碼,包括咱們本身的服務器返回的錯誤碼進行一個邏輯處理。
Service.interceptors.response.use(res => {
 
 //對響應數據作些事
 // if (res.data && !res.data.success) {
 //     Message({
 //         // 餓了麼的消息彈窗組件,相似toast
 //         showClose: true,
 //         message: res.data.error.message.message ?
 //         res.data.error.message.message :
 //         res.data.error.message,
 //         type: "error"
 //     });
 //     return Promise.reject(res.data.error.message);
 // }
 return res;
}, (error) => {

 // 錯誤處理方式1:
//   if (error.data) {
//     switch (error.data.code) {
//       case 401:
//         // 返回 401 清除token信息並跳轉到登陸頁面
//         // store.commit("del_token");
//         router.push({
//           path: "/login",
//           //   記錄原來的頁面路徑用於登陸後調回原頁面
//           query: {
//             redirect: router.currentRoute.fullPath
//           }
//         });
//         break;
//     }
//   }


 // 錯誤處理方式2:
 // 用戶登陸的時候會拿到一個基礎信息,好比用戶名,token,過時時間戳
 // 直接丟localStorage或者sessionStorage
 if (!window.localStorage.getItem("username")) {
   // 如果接口訪問的時候沒有發現有鑑權的基礎信息,直接返回登陸頁
   router.push({
     path: "/login"
  });
} else {
     // 下面是接口回調的satus ,由於我作了一些錯誤頁面,因此都會指向對應的報錯頁面
     if (error.response.status === 403) {
       router.push({
         path: "/error/403"
      });
    }
     if (error.response.status === 500) {
       router.push({
         path: "/error/500"
      });
    }
     if (error.response.status === 502) {
       router.push({
         path: "/error/502"
      });
    }
     if (error.response.status === 404) {
       router.push({
         path: "/error/404"
      });
    }
   
}
 // 返回 response 裏的錯誤信息
 let errorInfo = error.data.error ? error.data.error.message : error.data;
 return Promise.reject(errorInfo);

})
//封裝後導出
export default Service;

這種方法使用方式有兩種:

使用方式1:

1:全局配置:在main.js文件裏導入封裝的axios文件

import axios from '@/Axios/axios';

2:綁定到Vue實例

Vue.prototype.$axios= axios; //在其餘vue組件中就能夠this.axios調用使用:

3:在須要使用的單文件VUE組件裏面直接使用(由於是全局配置,在使用的單文件裏面不須要引入)

this.$axios.get(url,{params:{ID:888}}).then(res=>{}).catch(error=>{})
this.$axios.post(url,{id:888,name:"sdsdsd"}).then(res=>{}).catch(error=>{})

使用方式2:

在Axios文件夾下(或者其餘文件夾)先新建一個api(任意名稱)文件:api.js

1:該文件裏面下業務接口請求相關的函數:

// 封裝後使用的方式
import request from "@/Axios/axios.js"
export function tableList(query){
  return request({
      url: 'http://yapi.demo.qunar.com/mock/27844/apitest/list',
      method: 'get',
      params: query
  })
}

export function goodsList(query){
return request({
    url: 'http://yapi.demo.qunar.com/mock/27844/apitest/list',
    method: 'get',
    params: query
})
}

2:在須要使用的單文件裏面導入須要調用的接口函數

好比:home.vue單文件裏面

<template>
   <div class="mainBox">
       <table-component v-if="data.length>0" :goodslist="data"></table-component>
   </div>
</template>
<style rel="stylesheet/scss" lang="scss" scoped></style>
<script>
// 導入接口函數
import {tableList}  from "../Axios/api.js" ;
import tableComponent from "@/view/table/table";
export default {
   data() {
      return {
           data:[]
      }
  },
   mounted() {
       this.getData()
  },
   methods:{
       getData(){
           //使用接口函數
           tableList().then(res=>{
               console.log(res.data);
               this.data = res.data.list
          })
      }
  },
   components: {
       tableComponent
  },
}
</script>
相關文章
相關標籤/搜索