對於基於promise的HTTP庫axios的二次封裝

對於前端開發者來說,對於封裝自己的組件庫或者API,可能是再常見不過的事了。
所以現在我們自己來對axios進行二次封裝,對請求api的集中式管理,使axios使用起來更加方便快捷。
以下都是基於vue-cli下進行,用其它方式搭建項目的,需要稍作修改。(末尾有源碼)
既然說是對axios的二次封裝,那就先安裝axios吧,在項目的跟目錄下打開終端,並輸入 npm install axios -s 回車,等待安裝成功即可。(這是一句廢話)
先在src目錄先,新建一個目錄用於存放一些中間封裝的方法的文件夾,我喜歡命名爲function,在此目錄下再新建一個js文件,該文件就是對axios的二次封裝,我把它命名爲request.js。
當然了,既然是對axios的封裝,那麼就先把axios引入吧

import axios from 'axios'  //將axios 引入 需要先安裝 安裝方式:npm install axios -s
import { baseURL } from "../config/baseUrl.js"  //將域名引入   域名模塊化 方便後續管理

上面的baseURL是我把域名抽離出來,方便管理,畢竟本地開發用的是本地服務器,上線後用的是公網服務器,域名都是不一樣的。
新建一個類來對axios進行封裝

class Http{
  constructor (baseUrl = baseURL){
     this.baseUrl = baseUrl;
     this.lists = []; //每次發送請求將請求的url寫入數組中
  }
}

在構造函數 constructor 中傳入baseUrl,當沒傳入baseUrl 會使用默認的baseUrl(也就是上述中抽離出去的baseUrl),什麼是baseUrl呢?就是請求地址的公共部分,例如:請求地址的 協議+域名(IP)+端口號,例如我們有個接口叫做 http://localhost:8080/api/useer/getUserInfo 前面http://localhost:8080/ 這部分就叫做公共部分

添加全局設置

//全局設置
setInstanceConfig(){
  const config = {
    baseURL : this.baseUrl, //設置域名
    header:{  //統一設置請求頭
      'Content-Type' : 'application/x-www-form-urlencoded;charset=UTF-8'
      //如果將token放入請求頭供服務端驗證 也是放在這裏 如:
      //'Authorization': $store.getters.token
 
    },
    timeout:8000 //設置超時時間
  };
  return config;
}

setInstanceConfig方法中,對全局的公共部分進行設置,例如域名,請求頭,還有如果有token驗證,也將token包裝進去,當然了,很多人也喜歡將token通過get請求發送到服務端驗證,不過筆者更喜歡這種將token包裝進請求頭,這個需要前後端溝通。

設置攔截器,使用axios有個很大的好處就是它支持請求響應攔截。

interceptors(instance){
  //請求攔截
  instance.interceptors.request.use(config =>{
    //此處可添加全局的loading
    if(this.lists.length == 0){//判斷是否爲第一個請求
      //觸發loading
    }
    this.lists[config.url] = true; //將url保存進數組
    return config;  //將config返回
 
  },err =>{
      return Promise.reject(error);
  })
  //響應攔截
  instance.interceptors.response.use(res =>{
    delete this.lists[res.config.url]; //以響應,刪除lists該請求
 
    if(this.lists.length == 0){ //如果僅剩一個請求並請求完畢
       //取消loading
    }
     return res; //這裏就是響應的數據,可以在這裏做一些處理再返回,方便我們使用
  },err=>{
    delete this.lists[res.config.url]; //以響應,刪除lits中的該請求
    if(this.lists.length == 0){ //如果僅剩一個請求並請求完畢
      //取消loading
   }
    return Promise.reject(error);
  })
}

interceptors 方法傳入的是一個axios實例,通過這個實例設置axios的請求響應***,我們發送請求時顯示一個loading,請求結束後將loading取消通常也是在這裏設置。然後,代碼中的lists作用就是,當有發送請求時將請求的url存入數組,每當完成一個請求就刪除一個url,直至所有的請求都完成後,取消loading 這樣的好處就是無論有多少請求都只顯示一個loading,不然當首屏加載的時候,有多個請求,顯示一大堆loading,這無疑給頁面也造成了不小的負擔。

封裝一個請求的函數

request(options){
   const instance = axios.create(); //創建一個axios實例
   options =  Object.assign(this.setInstanceConfig(),options); //將全局設置與傳入的設置合併,但有相同時,後者覆蓋前者
   this.interceptors(instance); //設置攔截器
   return instance(options); //返回
}

request函數傳入的是一個帶着設置與參數的對象,我們需要時只要調用該類的次方法就可以了。
最後將該類暴露出去

export default Http;

然後附上上述整個類的完整代碼

import axios from 'axios'  //將axios 引入 需要先安裝 安裝方式:npm install axios -s
import { baseURL } from "../config/baseUrl.js"  //將域名引入   域名模塊化 方便後續管理
 
class Http{
 
  constructor (baseUrl = baseURL){
     this.baseUrl = baseUrl;
     this.lists = []; //每次發送請求可將請求的url寫入數組
  }
  //全局設置
  getInstanceConfig(){
    const config = {
      baseURL : this.baseUrl, //設置域名
      header:{  //統一設置請求頭
        'Content-Type' : 'application/x-www-form-urlencoded;charset=UTF-8'
        //如果將token放入請求頭供服務端驗證 也是放在這裏 如:
        //'Authorization': $store.getters.token
 
      },
      timeout:8000 //設置超時時間
    };
    return config;
  }
  //***
  interceptors(instance){
    //請求攔截
    instance.interceptors.request.use(config =>{
      //此處可添加全局的loading
      if(this.lists.length == 0){//判斷是否爲第一個請求
        //觸發loading
      }
      this.lists[config.url] = true; //將url保存進數組
      console.log(config)
      return config;
 
    },err =>{
        return Promise.reject(error);
    })
    //響應攔截
    instance.interceptors.response.use(res =>{
      delete this.lists[res.config.url]; //以響應,刪除lists該請求
 
      if(this.lists.length == 0){ //如果僅剩一個請求並請求完畢
         //取消loading
      }
       return res;
    },err=>{
      delete this.lists[res.config.url]; //以響應,刪除lits中的該請求
      if(this.lists.length == 0){ //如果僅剩一個請求並請求完畢
        //取消loading
     }
      return Promise.reject(error);
    })
  }
  request(options){
     const instance = axios.create();
     options =  Object.assign(this.getInstanceConfig(),options);
     this.interceptors(instance);
     return instance(options);
  }
}
 
export default Http;

對了,還要在你的異步庫中(就新建一個文件夾叫api然後所有的異步操作包裝在這個文件夾下),新建一個文件(名字隨便起,我給它命名叫axios)然後在裏面實例化這個類

import Http from '../function/request.js'
const http = new Http();
export default http;

然後就是最後的引用了,在你需要引用的地方引用實例這個對象,然後調用request方法

import http from './axios.js'
//GET請求
 http.request({
    url:'slider/listSliders.action',
    method:'get'
  }).then(res=>{
 
  })
//POST請求
http.request({
    url:'user/login.action',
    method:'post',
    data:{
      username: "",
      password: ""
    }
  }).then(res=>{
 
  })

OK,以上就是關於axios二次封裝的所有步驟了,歡迎指正交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章