axios的二次封装

206 阅读3分钟

1. 预先知识

1.1 axios.create创建axios实例

const instance = axios.create({
    baseURL,
    timeout,
    headers
})
  • baseURL是发送网路请求的根URL,后面的请求可以在这个baseURL的基础上简写URL
  • timeout是设置请求超时的时间
  • 其中headers是一个请求头对象

1.2 axios.request请求

axios.request({
    url,
    method,
    params...
}).then(res=>{
    处理请求成功...
}).catch(err=>{
    处理请求失败...
})
  • url 是api接口
  • method 是请求方法put/get
  • params 是请求携带的参数
  • get请求使用params,post请求使用data携带参数

1.3 axios.get请求

axios.get(url,{
        params:{
            参数
            id:xxxxx
    }
}).then(res=>{
    处理请求成功...
}).catch(err=>{
    处理请求失败...
})
  • 第一个参数是url
  • 第二个参数是config配置项,是一个对象,其中可以通过params对象传递参数

1.4 axios.post请求

默认写法axios.post(url,data,config)
1.data和config分开,这里不配置config
    axios.post(url,{
        username,
        password
    }).then(res=>{
    处理请求成功...
    }).catch(err=>{
        处理请求失败...
    })

2.data写在config里面,第二个参数是config,将data此内容写在config里面了
    axios.post(url,{
        data:{
            username,
            password
        }
    }).then(res=>{
    处理请求成功...
    }).catch(err=>{
        处理请求失败...
    })

1.5 创建一个axios实例并配置响应/请求拦截器

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

2.创建实例拦截器
const **requestInterceptor** = instance.interceptors.request.use(res=>{

},err=>{

})

instance.interceptors.response.use(res=>{

},err=>{
    
})

3.移除拦截器
instance.interceptors.response.eject(**requestInterceptor**)

2. axios二次封装

2.1 目录结构

  • src
    • router
    • store
      • modules
        • user.js(user状态管理器)
      • index.js(配置pinia)
    • service(发送请求)
      • modules(不同模块发送网络请求)
        • user.js(获取用户数据)
        • menu.js(获取菜单数据)
      • request(进行二次封装)
        • index.js(主文件)
        • config.js(配置文件)
      • index.js(接口导出)

大致思路

  • 在service/request/index.js中封装一个类,在service/modules/user.js中通过该类的实例封装不同模块的网络请求,比如user.js就将与用户有关的请求封装到一起
  • 然后在store/modules/user.js中将上述service/modules/user.js中的请求方法调用,并将数据存储在store/modules/user.js状态管理器中

2.2 service/request/index.js

import axios from 'axios';
import { baseURL, timeout } from './config.js';
// import { useCookies } from '@vueuse/integrations/useCookies';
import { getToken } from '@/hooks/cookies';
import { notification } from '@/hooks/notice';
import useUserInfo from '@/stores/modules/userInfo';

class Request {
    constructor(baseURL, timeout) {
        this.instance = axios.create({
            baseURL,
            timeout,
        });

        //在请求拦截中设置每次请求都要携带的token
        this.instance.interceptors.request.use(
            config => {
                // const cookies = useCookies();
                // const token = cookies.get('token');
                const token = getToken();
                if (token) {
                    config.headers['token'] = token;
                }
                return config;
            },
            err => {
                return Promise.reject(err);
            }
        );

        //处理响应拦截
        this.instance.interceptors.response.use(
            res => {
                return res.data.data;
            },
            err => {
                // ElNotification({
                //     message: err.response.data.msg || '请求失败',
                //     type: 'error',
                //     duration:3000
                // })
                const userInfo = useUserInfo();
                const msg = err.response.data.msg || '请求失败';
                if (msg == '非法token,请先登录!') {
                    userInfo.fetchLogout().finally(() => location.reload());
                }
                notification(msg, 'error');
                return Promise.reject(err);
            }
        );
    }
    //所有请求都是通过request进行发送的
    request(config) {
        return new Promise((resolve, reject) => {
            this.instance
                .request(config)
                .then(res => {
                    resolve(res);
                })
                .catch(err => {
                    reject(err);
                });
        });
    }

    get(config) {
        return this.request({ ...config, method: 'get' });
    }

    post(config) {
        return this.request({ ...config, method: 'post' });
    }
}
export default new Request(baseURL, timeout);

2.3 service/modules/user.js

import Request from '../Request';
export function 方法1() {
    return Request.get({
        url: 'admin/rule/1',
    });
}
export function 方法2(data) {
    return Request.get({
        url: 'admin/statistics3',
        params: {
            data
        }
    })
}
export function 方法3(data) {
    return Request.post({
        url: 'admin/rule',
        params: {
            ...data,
        },
    });
}
  • 上面的几个导出方法都是从写过的menus.js中复制来的,便于理解post和get的写法,实际情况还是得根据实际情况而定

2.4 store/modules/user.js

import { defineStore } from 'pinia';
import {
    方法1,
    方法2,
    方法3
} from '@/services/modules/user';

const useAccessStore = defineStore('accessStore', {
    state: () => ({
        list: [],
        rules: [],
        totalCount: 0,
    }),
    actions: {
        async fetch1() {
            const res = await 方法1();
            this.list = res.list;
            this.rules = res.rules;
            this.totalCount = res.totalCount;
        },
        async fetch2(data) {
            const res = await 方法2(data);
            console.log(res);
        },
        async fetch3(data) {
            const res = await 方法3(data);
            console.log(res);
        },
    },
});
export default useAccessStore;
  • 最后在不同的模块中通过状态管理调用上述三个异步请求的方法即可进行数据请求

听了大佬coderwhy的课做的总结