Vue3封装axios请求

233 阅读2分钟

一、安装

npm install axios --save

二、创建目录

三、封装axios

1、引入

import axios from "axios";// 安装axios
import QS from 'qs'; // 引入qs模块

2、环境切换

    //开发模式
if (process.env.NODE_ENV == 'development') {    
    axios.defaults.baseURL = 'https://www.baidu.com';} 
    //测试模式
else if (process.env.NODE_ENV == 'debug') {    
    axios.defaults.baseURL = 'https://www.ceshi.com';
} 
    //生产模式
else if (process.env.NODE_ENV == 'production') {    
    axios.defaults.baseURL = 'https://www.production.com';
}

3、设置请求超时时间

axios.defaults.timeout = 10000;

4、添加请求拦截器

instance.interceptors.request.use(function (config) {
        // 在请求之前做些什么
        return config;
    }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
    });

5、添加请求拦截器

instance.interceptors.response.use(function (response) {
        // 对响应数据做些什么
        let { data } = response //结构
        return data;
    }, function (error) {
        //请求失败重连
        if (error.code == "ECONNABORTED" && error.message.includes('timeout')) {
            if (error.config.num) {
                error.config.num++
            } else {
                error.config.num = 1
            }
            if (error.config.num > 3) {
                return Promise.reject(error)
            }
            error.config.timeout = error.config.timeout * (error.config.num + 1)
            return instance(error.config)
        }
        // 处理响应错误
        return Promise.reject(error);
    });

6、最后抛出

  export default instance

完整代码奉上

import axios from 'axios'


const instance = axios.create();
instance.defaults.timeout = 1000;


if (process.env.NODE_ENV == 'development') {    
    axios.defaults.baseURL = 'https://www.baidu.com';} 
    //测试模式
else if (process.env.NODE_ENV == 'debug') {    
    axios.defaults.baseURL = 'https://www.ceshi.com';
} 
    //生产模式
else if (process.env.NODE_ENV == 'production') {    
    axios.defaults.baseURL = 'https://www.production.com';
}


// Add a request interceptor
instance.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
instance.interceptors.response.use(function (response) {
    // Do something with response data
    return response.data;
}, function (error) {
    if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
        if (error.config.num) {
            error.config.num++
        } else {
            error.config.num = 1
        }
        if (error.config.num > 3) {
            return Promise.reject(error)
        }
        error.config.timeout = error.config.timeout * (error.config.num + 1)
        return instance(error.config)
    }
    // Do something with response error
    return Promise.reject(error);
});


export default instance

使用

首先我们先封装一个共同请求的接口API

1、创建目录

2、引入封装的axios

import request from '../utils/request'

3、使用

//多个抛出
export const Login = (data) => {
    return axios({
        url: '/api/auth/login',
        method: 'post',
        data
    })
}

axios的二次封装和使用方式就是以上全部代码,具体的封装内容根据具体的业务场景和性能需求来封装

下面是一个TS的一个封装

import axios from 'axios';
import type { InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import { FrownOutlined } from '@ant-design/icons-vue';
import { notification } from 'ant-design-vue';
// import { useRouter } from 'vue-router';
import router from "@/router"
import {  h } from 'vue';
// const router=useRouter()
interface ResponseData {
    code: number;
    data?: any;
    msg?: string;
}
// 创建axios实例
const service = axios.create({
    baseURL: '/api', // api的base_url
    timeout: 5000 // 请求超时时间
})
// 请求拦截器
service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        //获取token传给后端,因为我们有后端的auth验证
        let user: any = localStorage.getItem('user')
        let { token='' } = JSON.parse(user)||{}
        token && (config.headers.Authorization = `Baber ${token}`)
        return config
    },
    (error: any) => {
        return Promise.reject(error)
    }
) 

// 响应拦截器
service.interceptors.response.use(
    (response: AxiosResponse) => {
        // const res = response.data as ResponseData
        // 统一处理错误
        return response.data || {}
    },
    (error: any) => {
        // 统一处理错误
        console.log(error)
        let { response: { data, status } } = error
        if (status == 401) {
            notification.open({
                message: data,
                icon: () => h(FrownOutlined, { style: 'color: #108ee9' }),
            })
            console.log(1)
            setTimeout(()=>{
                //返回上一个被拦截的页面
                router.replace({ path: '/login', query: { redirect: router.currentRoute.value.fullPath }})
            },1000)
        }
        // { path: "/", query: { redirect: router.currentRoute.value.fullpath } }
        return Promise.reject(error)
    }
)
export default service;