关于对axios进行简单的二次封装

初识Axios二次封装

首先,我们需要明白为什么需要二次封装axios,在我们项目的实际开发过程中需要token,我们对于每个请求都需要附带一个请求字段 Authorization,但是我们不可能在每个请求的时候都写一遍,所以我们就需要利用axios的请求拦截,为我们的请求附带上Authorization字段。
其次,在后端服务为我们返回的响应中,我们会接收到对应的返回状态码,我们需要对这些状态码进行判断,并且需要展示给用户,例如状态码401,代表token过期。我们可以利用axios的响应拦截自动识别状态码,并且将对应的信息展示给用户,提高我们的开发效率。
最后,axios二次封装可以规范我们的请求风格,我们只需要传递一个options对象,对象包含请求方法method,请求参数data,请求路径url…。我们只需要传递这样一个对象,即可快速完成一个请求。
以上只是简单介绍axios二次封装的好处,总体来说,二次封装axios能帮助我们规范化、快速化地完成一个服务请求。
下面就让我们了解如何进行二次封装axios。

Axios二次封装的整体思路

1.创建一个axios实例对象。
2.对axios请求进行请求拦截。
3.进行响应拦截。
4.封装请求方法。
5.导出axios实例对象。
6.将axios实例对象挂载到vue原型上,方便使用。

Axios二次封装的完整实例

/**
 * 封装axios请求
 */
import axios from 'axios';
import config from './../config'//环境配置封装文件
import {ElMessage} from 'element-plus'
import router from './../router'
import storage from './storage' //localStorage的二次封装
const TOKEN_INVALID = 'Token验证失败,请重新登录';
const NETWORK_ERROR = '网络请求异常,请稍后再试'

//创建axios实例对象,添加全局配置
const service = axios.create({
    baseURL:config.baseApi,
    timeout:8000,  
})

//请求拦截
service.interceptors.request.use((req)=>{
    //TODO:这里做一些请求拦截的处理
    const headers = req.headers;//获取请求头
    const {token} = storage.getItem('userInfo');//获取本地存储中的userInfo,解构出token
    if(!headers.Authorization) headers.Authorization = `Bearer ${token}`;//附带上auth请求字段
    return req;//返回请求对象
})

//响应拦截
service.interceptors.response.use((res)=>{
    //TODO:这里做一些响应拦截
    const {code ,data ,msg} = res.data;
    if(code === 200){
        return data;//若请求返回状态码为200,直接返回data数据,不用再返回响应对象res
    }else if(code === 50001){
    	  //token过期
        ElMessage.error(TOKEN_INVALID);
        setTimeout(()=>{
            router.push('/login');
        },1500)
        return Promise.reject(TOKEN_INVALID);//重点!需要返回一个Promise的reject对象。
    }else{
        ElMessage.error(msg || NETWORK_ERROR);
        return Promise.reject(msg || NETWORK_ERROR);
    }

})
/**
 * 请求核心函数
 * @param {*} options 请求配置
 * @returns axios实例对象
 */
function request(options){
    options.method = options.method || 'get';//默认为get请求方法
    if(options.method.toLowerCase() === 'get'){//如果为get请求方法,需要将data转化为params
        options.params = options.data;
    }
    let isMock = config.mock;//查看是否使用mock接口
    if(typeof options.mock != 'undefined'){
        isMock = options.mock;
    }
    if(config.env === 'prod'){
        service.defaults.baseURL = config.baseApi
    }else{
        service.defaults.baseURL = isMock? config.mockApi : config.baseApi
    }
    return service(options)//返回一个Promise对象
}

  /**组件中调用request方法
	this.$request({
      url: "/users/login",
      method: "post",
      data: {},
      mock:false,
  	}).then((res)=>{}).catch((err)=>{})
  */


//导出axios实例对象
export default request;

对于上述代码的mock接口,其实就是当我们后端服务接口还没完成时,我们前端开发人员可以使用mock接口快速模拟生成假数据,测试我们的请求是否有问题。这样就不必等后端服务接口开发完,我们才进行测试我们的请求书否正确。
个人推荐使用fastmock,apipost进行模拟mock接口。
mock使用了解

如何使用Axios二次封装请求

对于使用我们封装完的axios,只需要在项目根目录下的main.js中进行挂载即可。

import request from "./utils/request.js";
import storage from "./utils/storage.js";

Vue3项目使用:
app.config.globalProperties.$request = request;//axios二次封装
app.config.globalProperties.$storage = storage;//localstorage二次封装

vue2项目使用:
Vue.prototype.$request = request;
Vue.prototype.$storage = storage;

附录:如何在vue中获取环境变量(了解)

在我们项目实际开发过程中,有分开发环境dev、测试环境test、生产环境prod。在每个环境中,对应的baseUrl都是不一样的,但是我们不可能手动去修改baseUrl,这样不仅麻烦,且容易出错。因此,我们需要在项目运行时自动获取当前对应的环境,然后获取该环境所对应的baseUrl。

首先,我们需要在项目根目录下创建对应的env环境文件,例如

.env.dev、.env.test、.env.prod

.env.dev文件
NODE_ENV=dev

.env.test文件
NODE_ENV=test

.env.prod文件
NODE_ENV=prod

接着,我们需要在package.json文件中,对启动命令添加环境。

"scripts": {
    "dev": "vue-cli-service serve --mode dev",
    "build": "vue-cli-service build"
  },

最后,创建一个环境配置封装文件

/**
 * 环境配置封装
 * 
 */
//默认生产环境
const env = import.meta.env.MODE || 'prod';  
//vue2通过process.env.NODE_ENV获取环境变量
const EnvConfig = {
    dev:{
        baseApi:'xxx',
        mockApi:'xxx'
    },
    test:{
        baseApi:'xxx',
        mockApi:'xxx'
    },
    prod:{
        baseApi:'xxx',
        mockApi:'xxx'
    }
}
export default{
    env,
    mock:false,
    namespace:'manager',
    ...EnvConfig[env]
}

附录:如何封装LocalStorage(了解)

对于封装localstorage作者就不再做过多叙述,下面直接展示封装案例。

/**
 * storage二次封装
 */

import config from './../config' //环境配置文件
export default{
    setItem(key,val){
        let storage = this.getStorage();
        storage[key] = val;
        window.localStorage.setItem(config.namespace,JSON.stringify(storage));
    },
    getItem(key){
        return this.getStorage()[key];
    },
    getStorage(){
        return JSON.parse(window.localStorage.getItem(config.namespace) || "{}");
    },
    clearItem(key){
        let storage = this.getStorage();
        delete storage[key];//关键!
        window.localStorage.setItem(config.namespace,JSON.stringify(storage));
    },
    clearAll(){
        window.localStorage.clear();
    }
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

insaneh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值