Vue3 现在现已越来越多小伙伴用上了,在许多技能群中关于Vue3的评价是很高的。在技能博客、群里也会见到许多小伙伴展示自己的 vue3 代码块以及关于vue3项目建立的一些心得,我自己项目也采用了 vite+vue3开发,结合网上的资源我发现关于项目整体大架构,比方 状况办理 pinia、开发构建 vite 、UI 结构 element-plusvantantd-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 地址

喜爱的小伙伴顺手点个 哦,多多支撑!