Vue3
现在现已越来越多小伙伴用上了,在许多技能群中关于Vue3
的评价是很高的。在技能博客、群里也会见到许多小伙伴展示自己的 vue3 代码块以及关于vue3项目建立的一些心得,我自己项目也采用了 vite+vue3
开发,结合网上的资源我发现关于项目整体大架构,比方 状况办理 pinia
、开发构建 vite
、UI 结构 element-plus
、vant
、antd-vue
等主流结构,网络恳求 axios
现已有很成熟的建立运用计划了。咱们搞事务开发,基本上围绕着网络恳求打交道,这儿和我们共享如何在vue3书写出好保护、质量牢靠的事务API恳求。
这儿列出我所知的恳求运用的计划
- 二次封装axios、文件夹统一办理API恳求,回来一个
Promise
,在组件中运用链式调用 - 二次封装axios、文件夹统一办理API恳求,回来一个
Promise
,在组件中运用async/await
运用 - 二次封装axios、全局注入axios,组件内直接调用中这个实例去传参数调用
- 直接运用 axios 恳求(打了重复冗杂的代码,这儿只做举例,不推荐 ❌)
我信任许多小伙伴都属于以上的运用计划,我会逐一和我们分析,谈一下关于 vue3 网络恳求
这块的见地。
分析
二次封装 Axios
const axiosInstance = axios.create({
baseURL: import.meta.env.VITE_SCREEN_BASE_URL,
timeout: 1_000 * 10
});
// ... 省掉拦截器
办理API的文件夹
export function getData(params,options){
return new Promise((resolve, reject) => {
axiosInstance({
url,
params,
...options,
})
.then((res) => {
resolve(res?.data?.data);
})
.catch((err) => {
reject(err);
});
}
}
链式调用,比较传统
const data = ref()
getData({...xxx},{...xxx}).then((res)=>{
// ...这儿处理数据
data.value = res.data
}).catch(err=>{
// ...xxx
})
Async/Await 调用,比较高雅
const data = ref()
onMounted(async () => {
const res = await getData({...x},{...x})
data.value = res
}
Provide/Inject 调用,和链式用法基本共同
main.ts
import axios from 'axios'
import VueAxios from 'vue-axios'
app.use(VueAxios, axios)
app.provide('axios', app.config.globalProperties.axios)
App.vue
const axios: any = inject('axios') // inject axios
axios({url,data,...其他装备}).then() // 同上
观点
我信任许多小伙伴会比较喜爱第二种的async/await 的语法糖,比较高雅,简洁。在当今事务越来越复杂的环境下,咱们往往依靠许多东西,比方
-
多次恳求拿上一次的数据作为参数体。
-
某个值变化了又需求重新恳求。
-
或许某个值满意什么条件才开始恳求。
关于链式调用来说,是十分不利于代码阅读的,整个事务组件充斥着重复代码,十分不利于保护。
关于async/await 好像很好的解决了以上的问题,有同学说 ,await拿上一次的很便利啊,我还能加判别条件让它是否要恳求,还能监听依靠再继续恳求,这儿咱们会发现,async/await 比链式高雅太多了,代码量也少了许多,但是,你总不可能这一个文件又加判别条件让它是否要恳求,别的一个文件又需求依靠恳求,这样文件一多,也存在许多代码重复。
这儿咱们可以把依靠恳求,判别条件是否发起恳求这些封装成起来,有履行 async/await 的办法,又有这些依靠恳求的功用模块一起联合运用,而用户只需求传递需求敞开的功用装备即可;
确实,咱们代码需求复用,需求逻辑复用
const useAxios = (service,option)=>{ const data = ref() const run = async ()=>{ const res = await service() data.value = res } // 是否满意条件 if(option.ready){ run() } // 依靠重新恳求 watch(option.deps,()=>{ run() }) return { data, run } }
以上的写法是hook写法,也是我今天倡议我们运用的。我敢说,许多同学从vue2过渡来vue3的,对这块这样运用的触摸的很少。运用高质量牢靠的恳求hook我信任后面会成为vue3开发的一个趋势,下面我展示一下事务中的运用流程,展示它的魅力
<template>
<div>读取值:{{ data }}</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { useAxios } from '..'
//、、、、、事务代码
//、、、、、事务代码
const { data } = useAxios(() => getData(), {
ready:true
deps:[依靠其他呼应式目标]
})
</script>
比方这块事务代码,用户直接拿到处理好的恳求的data,它是一个呼应式,所以事务层省去了一个声明呼应式目标来保存数据的代码,ready判别条件,事务层又被砍去一个条件判别函数,依靠刷新,砍去书写watch的代码,用户只需求重视装备即可,咱们会发现它是通过run办法调用触发恳求的,那么,咱们的防抖、节省函数还不是相加就加吗,所以这样的做法,是不是很简洁。
这一块的拓展性极强,你可以拓展 loading状况、params等出去。因为回来一个promise目标即可,所以意味着axios 和 request 这些都兼容,完全将恳求这块的功用性的模块从事务层脱离,用户只需求重视装备和API接口!
const { data } = useAxios(() => getData(), {
// 防抖
// 节省
// ready
// 依靠刷新
// 格式化恳求
...
})
几行装备下来,给人的感觉就清爽,并且保护起来那叫一个舒服。
运用
- 二次封装 axios 或许 其他恳求工具
- 封装恳求 hook 钩子
- 运用文件办理 API 接口,写的运用一个函数回来一个 promise 即可
- 事务层运用 hook 传装备即可
额定tip
封装带有ts提示的axios axiosInstance
和我们常用的一样,AxiosRequestConfig 类型从 axios
导出
const request = <ResponseType = unknown>(
url: string,
options?: AxiosRequestConfig<unknown>,
): Promise<ResponseType> => {
return new Promise((resolve, reject) => {
axiosInstance({
url,
...options,
})
.then((res) => {
resolve(res?.data?.data);
})
.catch((err) => {
reject(err);
});
});
};
恳求函数示例
AnalysisReportType
为 数据回来预定的 data
类型
export async function getListReports(
params?: {
reportGroup?: string | null;
sortCol?: 'visitUv' | 'uploadFileTime';
sortType?: string;
reportName?: string;
},
) {
return request<AnalysisReportType>('/platform/report/listReports', {
params: { ...params, sortType: 2 },
});
}
事务组件中
const { data } = useAxios(()=>getListReports(),{
ready:true,
...其他装备
})
拿来吧你
因为vueuse没有这块的功用,我针对事务层封装了一个 useRequest
钩子,自己公司现已用上,安全牢靠,满意事务 99% 需求,以下展示基本功用,更多具体见API文档
const {
loading: Ref<boolean>,
data?: Ref<TData>,
error?: Ref<Error>,
params: Ref<TParams || []>,
run: (...params: TParams) => void,
runAsync: (...params: TParams) => Promise<TData>,
refresh: () => void,
refreshAsync: () => Promise<TData>,
mutate: (data?: TData | ((oldData?: TData) => (TData | undefined))) => void,
cancel: () => void,
} = useRequest<TData, TParams>(
service: (...args: TParams) => Promise<TData>,
{
manual?: boolean,
defaultParams?: TParams,
formatResult?:(response:TData)=>any,
onBefore?: (params: TParams) => void,
onSuccess?: (data: TData, params: TParams) => void,
onError?: (e: Error, params: TParams) => void,
onFinally?: (params: TParams, data?: TData, e?: Error) => void,
}
);
useRequest 文档
Github 地址
喜爱的小伙伴顺手点个 哦,多多支撑!