我的VUE3的axios封装

一、主要思路

组件创建一个ref属性,控制局部的loading状态,将这个属性传入axios实例中,在请求开始的时候,设置为true,请求结束后,设置为false。

二、代码

// index.ts
import axios, {AxiosRequestConfig} from "axios"
import {useUserInfo} from "../store/moduls/userinfo";		// 用户登录信息的pinia
import {Ref} from "vue";			// ref的类型
import {useLayout} from "../store/moduls/layout";	// 全局loading的pinia



interface loadingtype {
    [prop: string]: Ref<boolean>
}

const loadingstorage: loadingtype = {} // 所有加载状态的仓库,key是url,value是ref数据,保证这边修改,那边同步修改

const excepturl:Array<string> = []        // 不需要防抖的url数组
let antiShakeurlList:Array<string> = [] // 被缓存的url数组

const BaseUrl = import.meta.env.VITE_RES_URL || "/proxy/"
const http = axios.create({
    // 联调
    // baseURL: process.env.NODE_ENV === 'mock' ? `/api/` : '/proxy/',
    baseURL: BaseUrl,
    // 是否跨站点访问控制请求
    withCredentials: false,
    // 返回树状数据大约需要5-6秒,设置最大超时为10秒
    timeout: 10000,
    // 请求数据拦截
    // transformRequest: [
    //     (data) => {
    //         return data
    //     },
    // ],
    validateStatus() {
        // 使用async-await,处理reject情况较为繁琐,所以全部返回resolve,在业务代码中处理异常
        return true
    },
    // 响应数据拦截
    transformResponse: [
        (data) => {
            if (typeof data === 'string' && data.startsWith('{') || data.startsWith('[')) {
                data = JSON.parse(data)
            }
            return data
        },
    ],
});


// 请求拦截器
http.interceptors.request.use(
    (config: AxiosRequestConfig) => {
        // 使用秘钥加密数据,暂时不做
        // 添加token
        const userInfo = useUserInfo()
        if (userInfo.token) {
            // @ts-ignore
            config.headers['Authorization'] = "www+" + userInfo.token
        }
        return config
    },
)


const request = (method: "post" | "get" | "put" | "delete", url: string, data: any = null, params: any = null, headers: any = null, loading: null | Ref<boolean>) => {
    // 判断是否是不防抖的url
    if(!excepturl.includes(url)){
        // 判断是否已经发起请求
        if(antiShakeurlList.includes(url)){
            return Promise.reject("别点这么快,想死啊!")
        }else{
        	// 将现在的url放入缓存列表
            antiShakeurlList.push(url)
        }
    }
    const loadingkey: string = url + new Date().getTime()
    // 如果没有传入局部loading,就打开全局loading遮罩
    if (loading != null) {
        console.log("自定义的loading")
        loading.value = true;
        loadingstorage[loadingkey] = loading
    }else{
        console.log("全局的loading")
        const mylayout = useLayout()
        mylayout.changezhezhao(true)
    }
    return new Promise((resolve, reject) => {
        http({method: method, url: url, data: data, params: params,headers:headers}).then(res => {
            // 请求成功,删除缓存的url
            antiShakeurlList = antiShakeurlList.filter(item=>item!==url)
            // 关闭loading            
            if(loadingstorage[loadingkey]){
                loadingstorage[loadingkey].value = false
                delete loadingstorage[loadingkey]
            }else{
                const mylayout = useLayout()
                mylayout.changezhezhao(false)
            }
            resolve(res)
        }).catch((error: Error) => {
            // 请求失败,删除缓存的url
            antiShakeurlList = antiShakeurlList.filter(item=>item!==url)
            // 关闭loading      
            if(loadingstorage[loadingkey]){
                loadingstorage[loadingkey].value = false
                delete loadingstorage[loadingkey]
            }else{
                const mylayout = useLayout()
                mylayout.changezhezhao(false)
            }
            console.log(error,"都有什么东西")
            if(error.message.search("timeout")){
                reject("请求超时")
            }else{
                reject(error.message)
            }
        })
    })
}

// 创建方法
export function json(url: string, data:any = null, loading: null | Ref<boolean> = null) {
    return request(
        "post",
        url,
        data,
        null,
        {'Content-Type': 'application/json;charset=utf-8',},
        loading,
    )
}

// 更新方法
export function update(url: string, data: any = null, id: string | null = null, loading: null | Ref<boolean> = null) {
    if (id) {
        return request(
            "put",
            url + id + "/",
            data,
            null,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    } else {
        return request(
            "put",
            url,
            data,
            null,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    }
}

// 删除方法
export function shanchu(url: string, data:any = null, id:string|null = null, loading: null | Ref<boolean> = null) {
    if (id) {
        return request(
            "delete",
            url + id + "/",
            null,
            data,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    } else {
        return request(
            "delete",
            url,
            null,
            data,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    }
}

// 单查方法
export function get(url: string, data:any = null, id:null|string = null, loading: null | Ref<boolean> =null) {
    if (id) {
        return request(
            "get",
            url + id + "/",
            null,
            data,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    } else {
        return request(
            "get",
            url,
            null,
            data,
            {'Content-Type': 'application/json;charset=utf-8',},
            loading,
        )
    }
}

// 群查方法
export function list(url: string, data:any = null, loading: null | Ref<boolean> = null) {
    return request(
        "get",
        url,
        null,
        data,
        {'Content-Type': 'application/json;charset=utf-8',},
        loading,
    )
}

// 表单创建方法
export function form(url: string, data:any = null, loading: null | Ref<boolean> = null) {
    return request(
        "post",
        url,
        data,
        null,
        {'Content-Type': 'application/x-www-form-urlencoded'},
        // transformRequest: [function (data) {
        //     let ret = ''
        //     for (const it in data) {
        //         ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
        //     }
        //     return ret
        // }]
        loading,
    )
}

三、使用

  menulist: (data: any,loading:Ref<boolean>|null=null) => list(api.menu, data,loading),   // 菜单管理群查
  menuget: (data: any, id:any = null,loading:Ref<boolean>|null=null) => get(api.menu, data, id,loading),   // 菜单管理单查
  menuadd: (data: any,loading:Ref<boolean>|null=null) => json(api.menu, data,loading),   // 菜单管理增加
  menuupdate: (data: any, id:any = null,loading:Ref<boolean>|null=null) => update(api.menu, data, id,loading),   // 菜单管理修改
  menudelete: (data: any, id:any = null,loading:Ref<boolean>|null=null) => shanchu(api.menu, data, id,loading),   // 菜单管理删除
  menufilter: (data: any, id:any = null,loading:Ref<boolean>|null=null) => get(api.menufilter, data, id,loading),   // 菜单管理过滤
  menuall: (data: any,loading:Ref<boolean>|null=null) => list(api.menuall, data,loading),     // 获取所有菜单
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值