V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
ScottHU
V2EX  ›  JavaScript

改变 axios 的用法后,我的工作效率提升了 3 倍

  •  
  •   ScottHU · 203 天前 · 5147 次点击
    这是一个创建于 203 天前的主题,其中的信息可能已经有所发展或是发生改变。

    实际场景下的请求问题

    作为前端开发,网络请求肯定是我们经常要面对的事情,在前端请求中,axios 和 fetch API 应该是我们最常用的请求工具了,它们在发送请求和接收响应数据已经做到了足够简单。

    但在实际项目中,为了达到更好的用户体验,我们还需要考虑下面这几个因素:

    1. 展示加载中的请求状态
    2. 展示请求错误状态
    3. 展示上传/下载文件的进度信息

    上面这些都需要我们编写额外的代码,增加了不少的工作量,你的请求代码可能是下面这样的,我们以 vue3 代码为示例。

    const loading = ref(false);  
    const data = ref({});  
    const error = ref(null);  
    const request = async () => { 
      try {  
        loading.value = true;  
        data.value = await axios.get('/xxx');  
      } catch (e) {  
        error.value = e;  
      }
      loading.value = false;  
    };
    onMounted(request);
    

    如果面对大量的 api ,这工作量可想而知,想到这时就有点头疼啊。有没有一种方法可以自动帮我处理这些逻辑,让请求代码看起来更简洁呢?

    解决

    我们可以用封装的思路,把上面这些都封装为一个简单的 use hook ,就可以很好地解决了,封装后的代码大概是下面这样的。

    export const useRequest = (url) => {
      const loading = ref(false);
      const data = ref({});
      const error = ref(null);
      const request = async () => {
        try {
          loading.value = true;
          data.value = await axios.get(url);
        } catch (e) {
          error.value = e;
        }
        loading.value = false;
      }
      onMounted(request);
    
      return {
        loading,
        data,
        error
      };
    }
    

    这是一个最简单的 use hook 实现,它帮我们解决了请求模板代码的问题。当然你还可以使用 use hook 封装更多更高级的请求功能,而这些功能现在不必你自己封装了,使用alova就可以了。

    alova 是一个轻量级的请求策略库,针对分页请求、表单提交、上传和下载文件等不同请求场景使用对应的请求模块,让开发者使用非常少量的代码就可以实现高可用性和高流畅性的请求功能,这意味着,你再也不需要自己绞尽脑汁编写请求优化代码,再也不需要自己维护请求数据和相关状态,你只需要选择并使用请求模块,设置参数后,alova 帮你搞定!

    在引入 alova 后,我的工作效率直接提高了 3 倍,强烈推荐给大家。

    你可以将 alova 理解成是 axios 或 fetch-api 等请求工具的一种武器装备,将 alova 与请求工具配合使用将会让它们变得更加强大。

    其实,alova 底层依然依赖 axios 或 fetch-api 等请求函数进行请求,因此你仍然可以使用你喜欢的请求库。

    以下是一个基于vue3+axios+alova的使用示例,alova 将自动为你创建请求相关的,可以直接用于视图的响应式状态,代码如下:

    可运行的示例点此去查看

    <template>
      <div v-if="loading">Loading...</div>
      <div v-else-if="error">{{ error.message }}</div>
      <span v-else>responseData: {{ data }}</span>
    </template>
    
    <script setup>
    import { createAlova, useRequest } from 'alova';
    import VueHook from 'alova/vue';
    import { axiosRequestAdapter } from '@alova/adapter-axios';
    
    const alovaInstance = createAlova({
      statesHook: VueHook,
    
      // 设置使用 axios 作为请求工具
      requestAdapter: axiosRequestAdapter()
    });
    
    const {
      // 加载状态
      loading,
    
      // 响应数据
      data,
    
      // 错误信息,请求错误时才有值
      error
    } = useRequest(alovaInstance.Get('/todoList'));
    </script>
    

    是不是非常 nice !!!之前需要我们自己实现的各种功能,alova 都帮我们做了。

    总结

    alova 目前提供了 8 种请求策略,如果你希望在不同的请求场景下方便地实现特定的请求需求,那千万别错过它哦。alova 还提供了缓存管理、请求共享等更多功能,可以覆盖绝大多数请求场景。

    所以,在你的下一个项目中,你也可以来试试 alova ,一定能给你带来更愉快的开发体验!

    结尾

    目前,alova 已经可以在 vue options ( vue2 和 vue3 )写法中完美使用了,点此查看详情。后续还会支持以下框架:

    • 函数式,如 solid/preact/qwik 。
    • class 式,如 angular/lit/stencil 。
    • options 式,如原生小程序(中国🇨🇳)

    如果觉得对你有用请帮忙点个赞或收藏!

    相关信息

    alova 官网

    alova Github 地址

    32 条回复    2023-10-08 16:25:17 +08:00
    8520ccc
        1
    8520ccc  
       203 天前 via iPhone
    ahook ?似乎也是提供这个功能的
    NessajCN
        2
    NessajCN  
       203 天前   ❤️ 7
    https://v2ex.com/t/948621
    被喷了上百楼又来了吗
    dropice7777777
        3
    dropice7777777  
       203 天前
    你们今天是集体出动了吗?掘金才刚看到推文,这里又看到了
    poorAshenOne
        4
    poorAshenOne  
       203 天前
    我用了之后是不是就能提前下班了
    BaiLinfeng
        5
    BaiLinfeng  
       203 天前
    我还以为是技术交流文章,仔细一看是推广广告啊
    MRG0
        6
    MRG0  
       203 天前
    比 axios 没有明显优势,咋立的项
    XIVN1987
        7
    XIVN1987  
       203 天前
    @poorAshenOne

    你老板就可以给你布置三倍任务了 ;-)
    a632079
        8
    a632079  
       203 天前 via iPhone   ❤️ 1
    这个不是 swr 做的事情么……😨 Nuxt 3 的话有内嵌的 useFetch useAsyncData……vite vue 的话,用 https://github.com/Kong/swrv 足以。楼主如果真要推广的话,不妨和这类库对比一下,给出数据来。而不是写软文……假设大家都不知道一样。
    haierspi
        9
    haierspi  
       203 天前
    老板: 看你天天没啥事... 工作很不饱和啊.. 要不签个字吧.. 把你工作交接下..
    FakerLeung
        10
    FakerLeung  
       203 天前
    上次还没被喷过瘾吗?
    jsq2627
        11
    jsq2627  
       203 天前
    这是不吸取教训吗。。
    Quarter
        12
    Quarter  
       203 天前 via Android
    好奇这个三倍是怎么得出来的
    webszy
        13
    webszy  
       203 天前
    没看出来比我自己封装的 axios 好在哪
    jorneyr
        14
    jorneyr  
       203 天前
    比这个还简洁?

    * [1] 普通 GET 请求
    * 提示: rsp 会自动推导出类型 Response<string>,不需要明确的写。
    * Rest.get<string>('/api/rest').then(rsp => {});
    *
    * Rest.data({ pageNumber: 3 }).get<string>('/api/rest').then((rsp: Response<string>) => {
    * console.log(rsp);
    * });
    *
    * 其他类型的请求只需要把 get<T>() 替换为对应的函数即可,参数配置部分一样。
    *
    * [2] 替换 url 中的变量: 下面的 URL 中 {bookId} 会被替换为 params 的参数 bookId 的值 23 ,得到请求的 url '/rest/books/23'
    * Rest.url('/rest/books/{bookId}').params({ bookId: 23 }).data({ name: 'C&S' }).update<boolean>().then(rsp => {
    * console.log(rsp);
    * });
    *
    * [3] 调用 useRequestBody() 使用 request body 传输复杂的 data 对象 (对象可以有多级属性)
    * Rest.url('/api/uid').data({
    * user: { username: 'Bob', password: '123456' },
    * company: 'App'
    * }).useRequestBody().create<User>().then(({ data: user, success, message }) => {
    * console.log(user);
    * });
    *
    * 默认使用 application/x-www-form-urlencoded 的方式,即普通表单的方式。
    *
    * [4] Axios 不支持同步请求,但可以在同一个函数里使用 async await 进行同步操作:
    * async function syncFunc() {
    * const r1 = await Rest.get('/api/rest1'); // r1 为 resolve 的参数。
    * const r2 = await Rest.data({ name: 'Goo' }).create<Foo>(/api/rest2');
    *
    * console.log(r1, r2);
    * }
    * 注: jQuery 的 Ajax 支持同步请求,但是新版本中也不推荐使用了,浏览器中会有警告。
    *
    * [5] 请求成功表示与服务器通信成功,不代码业务处理成功。
    * 使用 Rest.normalize() 根据 success 对响应统一的进行业务逻辑判断,success 为 true 表示业务处理成功,为 false 表示失败。
    * 代码中逻辑更关注成功业务处理,大多数时候都可以使用 Rest.normalize() 简化开发,除非 success 的值不足以判断,
    * 需要使用响应的 code 进行更多情况处理。
    *
    * [5.1] Api 接口文件中处理请求。
    * async function findTime(): Promise<number> {
    * return Rest.get<number>(url).then(({ data: time, success, message }) => {
    * // 提示: 参数里进行了一次解构是为了让调用者知道 data 的业务名称,方便代码的维护。
    * return Rest.normalize({ data: time, success, message });
    * });
    * }
    *
    * [5.2] Vue 文件中调用请求直接获取结果,忽略请求的细节,而且即使切换了 Api 的实现不需要修改 vue 中的代码 (如把 Axios 换为 fetch 实现)。
    * findTime().then((time: number) => {
    * console.log(time);
    * })
    * const time: number = await findTime();
    cnwhy
        15
    cnwhy  
       203 天前
    api 请求就是你的工作全部么,这种文章真恶心人
    justdoit123
        16
    justdoit123  
       203 天前   ❤️ 1
    来来来,细说 3 倍效率怎么计算出来的!为什么是 3 而不是 100 ?写 100 会不会更吸引人?
    duck2u
        17
    duck2u  
       203 天前
    useSWR
    duck2u
        18
    duck2u  
       203 天前
    怎么念,啊 low 哇?
    cppc
        19
    cppc  
       203 天前 via iPhone
    味太浓了,你不搞这种技俩就不会说话了是吧
    alleluya
        20
    alleluya  
       203 天前
    alova 我记得之前是不是有写过这种营销的文章? 而且这种 useRequest 式的封装 有很多选择啊 你这文章也没说明为啥一定要用你的 比别的好的地方在哪
    kneo
        21
    kneo  
       203 天前 via Android
    看到标题我就知道是广告。点进来单纯是确认下而已。别以为你赢了。
    Track13
        22
    Track13  
       203 天前 via Android
    真的太 low 👎🏻了。掘金发了几次,这里也不止一次。倒不是说这个包有多差,你们这样宣传,实在是难看。
    ztxcccc
        23
    ztxcccc  
       203 天前
    没事,被解雇了就没工作量了
    PTLin
        24
    PTLin  
       203 天前
    我感觉除了前端领域很少看见有人这么推广库,都是开源的东西这么推广图个啥呢,也赚不了多少钱
    redsun368573607
        25
    redsun368573607  
       203 天前
    大家误解了,文章写的是提升 3 倍,是现在工作量为以前 1/4 的意思,大家看少了
    0914xc
        26
    0914xc  
       203 天前 via iPhone   ❤️ 1
    说实话,我看到这个标题的时候,我思考过要不要点进来看。

    哎,还是没控制住自己,下次再也不看这种标题的内容了😒
    BwNVlwSq
        27
    BwNVlwSq  
       202 天前 via Android
    就这?
    lete
        28
    lete  
       202 天前
    一股掘金标题党的味道,没被喷够是吧?但凡换个标题也不会被喷成这样
    2chanriban
        29
    2chanriban  
       202 天前
    经典的‘掘金标题‘,精神污染是吧
    draymonder
        30
    draymonder  
       202 天前
    不是前端,想请教下,效率提升 3 倍,老板能给加 3 倍的工资不
    arfaWong
        31
    arfaWong  
       202 天前
    又来?
    99s
        32
    99s  
       202 天前
    不长记性
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   950 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 19:29 · PVG 03:29 · LAX 12:29 · JFK 15:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.