对于前端开发者来说,对于封装自己的组件库或者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二次封装的所有步骤了,欢迎指正交流。