大家好,我是vue-hooks-plus的作者,这里和大家分享一下属于Vue3的方便快捷的申请形式是怎么样的。

Vue3 当初曾经越来越多小伙伴用上了,在很多技术群中对于Vue3的评估是很高的,在技术博客、群里也会见到很多小伙伴展现本人的 Vue3 代码块以及对 Vue3 我的项目搭建的一些心得。

置信大部分我的项目采纳了 Vite+Vue3开发,联合网上的资源我发现对于我的项目整体大架构,比方 状态治理 pinia、开发构建 Vite 、UI 框架 Element-plusVantAntd-vue 等支流框架,网络申请 axios 曾经有很成熟的搭建应用计划了,咱们搞业务开发,基本上围绕着网络申请打交道,这里和大家聊聊鲜为人知的、好保护、品质牢靠的业务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.tsimport axios from 'axios'import VueAxios from 'vue-axios'app.use(VueAxios, axios)app.provide('axios', app.config.globalProperties.axios) App.vueconst axios: any = inject('axios')  // inject axiosaxios({url,data,...其余配置}).then() // 同上

认识

我置信很多小伙伴会比拟喜爱第二种的 async/await 的语法糖,比拟优雅,简洁。

在当今前端业务越来越简单的环境下,网络申请场景也会变得复杂起来,比方

  • 屡次申请拿上一次的数据作为参数体
  • 某个值变动了又须要从新申请
  • 或者某个值 满足条件 才开始申请。

    对于链式调用来说,是十分不利于代码浏览的,整个业务组件充斥着反复代码,十分不利于保护。

    对于 async/await 仿佛很好的解决了以上的问题,

    • 第一个 ,await拿上一次 申请参数 的很不便啊! ✅。
    • 第二个,某个值变动了须要从新申请,这里很多小伙伴会想到我把这个申请封装起来,放进watch外面监听执行 ✅
    • 第三个,在封装的申请函数中退出判断条件是否执行 ✅

    上述场景多个组件,多次重复操作,这样文件一多,也存在很多代码反复 ❌

✅ 正确思路

咱们须要将这些反复的操作进行封装成 hook,把依赖申请,判断条件是否发动申请这些封装成起来,有执行 async/await 的办法,又有这些依赖申请的功能模块一起联结应用,而用户只须要传递须要开启的性能配置即可;

什么是 hook ?

React 中的意思是将一个以 use 结尾,含react 状态和 effect 纯函数的内部代码挂入到它的节点当中。

Vue 中,我认为将 Vue 的 effect ,如 ref、watch、watchEffect 的内部代码放入vue中执行,也是挂入 hook

这里咱们命名 useRequest

 const useRequest = (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写法,外面应用到了 refwatch,很多小伙伴从Vue2过渡来Vue3的,对这块这样应用的接触的很少。应用高质量牢靠的申请hook我置信前面会成为Vue3开发的一个趋势,上面我展现一下业务中的应用流程,展示它的魅力

<template>  <div>读取值:{{ data }}</div></template><script lang="ts" setup>import { ref } from 'vue'import { useRequest } from '..' //、、、、、业务代码  //、、、、、业务代码 const { data } = useRequest(() => getData(), {  ready:true  deps:[依赖其余响应式对象]})</script>

比方这块业务代码,用户间接拿到解决好的申请的 data,它是一个响应式,所以业务层省去了一个申明响应式对象来保留数据的代码,ready 判断条件,业务层又被砍去一个条件判断函数,依赖刷新,砍去书写watch的代码,用户只须要关注配置即可,咱们会发现它是通过 run办法调用触发申请的,那么,咱们的防抖、节流函数只须要作用于 run 函数即可,所以这样的做法,是不是很简洁。

这一块的拓展性极强,你能够拓展 loading状态、params等进来。因为应用 async/await ,所以咱们治理的申请API返回一个promise对象即可,意味着axiosrequest 这些都兼容,齐全将申请这块的功能性的模块从业务层脱离,用户只须要关注配置和API接口!

const { data } = useRequest(() => getData(), { // 防抖// 节流// ready// 依赖刷新// 格式化申请 ...})

几行配置下来,给人的感觉就清新,而且保护起来那叫一个舒服。

Use

  • 二次封装 axios 或者 其余申请工具
  • 封装申请hook钩子
  • 应用文件治理 API 接口,写的应用一个函数返回一个 promise 即可
  • 业务层应用 hook 传配置即可

额定tip

封装带有ts提醒的axios axiosInstance 和大家罕用的一样,AxiosRequestConfig 类型从 axios 导出。 留神: 因为这里没写拦截器,所以返回了一个多余的new Promise 让大家直观的看到,只须要承受返回的一个 Promise 对象即可,实际上不论是 axios 还是 request 自身返回的都是 Promsie 对象 的。

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);      });  });};

须要配合拦截器截取 res.data.data

const request = <ResponseType = unknown>(  url: string,  options?: AxiosRequestConfig<unknown>,): Promise<ResponseType> => {  return  axiosInstance({url,...options}) };

申请函数示例 AnalysisReportType 为 数据返回预约的 data 类型,反对 ts

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 } = useRequest(()=>getListReports(),{  ready:true,  ...其余配置})

拿来吧你

因为vueuse没有这块的性能,我针对业务层写了一个 vue-hooks-plus库,残缺的测试用例笼罩,高质量牢靠,外面涵盖封装了一个 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 保姆级业务开发教程

useRequest 国内文档地址

Github 地址

喜爱的小伙伴棘手点个 star ,多多反对!

✨ 文档闪亮退场