vue axios 封装解析

vue axios 封装解析

示例代码

  • http.js
import axios from "axios";

//创建axios实例
const service = axios.create({
    baseURL: 'https://some-domain.com/api/',
    timeout: 5000,
});

//请求拦截器
service.interceptors.request.use(
    (config)=>{
        console.log(config)
        return config;
    },(error) => {
        return Promise.reject(error);
    }
)

//响应拦截器
service.interceptors.response.use(
    (response)=>{
        return response;
    },(error)=>{
        return Promise.reject(error);
    }
)

//对外暴露
export default service

  • api.js
import http from './http'

export const test = ()=>{
    return http({
        url:'/text/1',
        method:"POST"
    })
}

  • 引用
import {test} from "@/api/api"

  created(){
    test()
  },

解析

  1. http.js 中的内容,就是创建了一个统一的axios的请求实例,并将这个实例对外进行暴露

    也可以把这个实例原型prototype给全局一个axios

    //在src/main.js文件内引入axios,全局vue绑定一个$http指向axios
    import http from '@/api/http'
    Vue.prototype.$http = http
    
    //调用
      created(){
        // console.log(123)
        // test()
        this.$http.get('/12',{
          data:{}
        })
        this.$http({
          url:'/12',
          method:'get'
        })
      },
    
  2. 由于axios自己实现了一套拦截器,所以可以对在发送请求前利用拦截器对request请求的参数内容进行修改(包括不限于修改特点的请求参数内容,token,请求地址等),对response响应内容进行特点的处理(如特定返回的内容执行特定的结果)

  3. 对外暴露的是axios的实例,所以可以在引用的位置继续使用axios中的方法

    //示例
    import http from './http'
    
    export const test = ()=>{
        return http.get('/text/1',{ //就可以不需要指定method的方法类型了
           	data:{},
            ....
        })
    }
    

    image-20220815154128489

  4. 调用axios的方法时,会把相关的配置进行传递,在拦截器中打印中可以看出来,调用方法时,传递的参数会与默认的config的内容进行合并,如果存在同样的参数时,传递的参数的会覆盖掉已有的默认的config中的内容

image-20220815151400364

image-20220815152100795


所以在调用axios的方法时,传入自定义的参数,然后在拦截器中进行逻辑处理,用来实现不同的效果

  • 例如通过添加自定义参数type,实现向不同地址发请求
import http from './http'

let proxy = {
        protocol: 'https',
        host: '127.0.0.1',
        port: 9000
}

export const test = ()=>{
    return http({
        url:'/text/1',
        method:"POST",
        "type":"ce",
        proxy:proxy
    })
}
  • 拦截器处理
import axios from "axios";

//创建axios实例
const service = axios.create({
    baseURL: 'https://some-domain.com/api/',
    timeout: 5000,
});

//请求拦截器
service.interceptors.request.use(
    (config)=>{
        console.log(config)
        //判断请求参数中的内容,并进行修改
        if(config.type){
            if(config.type=="ce"){
                config.baseURL = "http://baidu.com"
            }
        }
        return config;
    },(error) => {
        return Promise.reject(error);
    }
)

//对外暴露
export default service

image-20220815152936744

这里面比较关键的点是,我们始终是使用的http.js中创建的axios实例,而不是每次都重新创建了一个新的实例

关于对axios的封装

  1. 设置成全局的,利用$去调用,没有特意的封装,相当于就是把自定义创建的axios变成全局的,代码简单,操作容易,复用差了点

  2. 将调用的接口,每个单独封装出来成一个js,结构上比较清楚,每个页面都需要引入,但是复用性高一点

    可以按照需求自行去决定,两张兼容着用也可以

利用axios自己的拦截器机制,已经可以实现绝大部分的场景了


axios拦截器

您可以在 或 处理请求或响应之前截获它们。then``catch

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  }, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    return Promise.reject(error);
  });

如果以后需要删除拦截器,则可以这样做。

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

您可以将拦截器添加到 axios 的自定义实例中。

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
posted @ 2022-08-15 16:10  STR少寒  阅读(249)  评论(0编辑  收藏  举报