在vue中不使用全局状态和事件的情况下的跨模块更新列表实践

393 阅读6分钟

在做 todo 应用的时候,我们常常会碰到这么一个需求吧:

  • 先进去 todo 列表页,点开某条 todo 项,进去编辑页把它编辑一下;
  • 编辑页保存了,我想回到列表页,看看我编辑的 todo 是不是同步更新过来了。

这其实就是一个跨页面或者说跨模块更新数据状态的场景吧。要做到这件事,以前我们通常用的方法可能是全局状态或者组件之间的事件通知。但使用这两种方式做起来总觉得很麻烦,有没有更方便的方法呢?

答案是当然有

使用 alova 的 updateState 就可以轻松搞定这件事了!它可以直接更新任意页面或组件中的响应数据,而不需要重新请求数据。

alova是一个轻量级的请求策略库,旨在简化接口的管理和使用。它可以让你以声明式实现复杂请求,你可以通过简单配置参数,即可实现复杂请求如请求共享、分页请求、表单提交、断点续传等,无需编写大量代码,提高开发效率,应用性能,减轻服务端压力。同时支持vue/react/svelte框架。如果你也喜欢 alovajs,请在Github 仓库中贡献一颗 star,这对我们非常重要。

我们可以在编辑页提交数据后直接更新列表页的状态。接下来我用一个实际的例子讲解一下它是如何做的。

1. 获取列表数据

在列表页组件,我们通过 useRequest 获取 todoList 数据,并在回调函数中保存请求方法实例,为了简化阅读,示例代码只写了实现的关键代码。

TodoList.vue

<template>
  <span v-if="loading">Loading</span>
  <ul>
    <li v-for="todo in data" :key="todo.id">
      <span>{{ todo.title }}</span>
      <button @click="handleEdit(todo.id)">编辑</button>
    </li>
  </ul>
</template>

<script setup>
import { useRequest } from 'alova';

const { loading, data } = useRequest(getTodoList);  
</script>

2. 编辑 todo 项

在编辑页组件,我们通过 useRequest 提交表单,获取的是当前编辑的这一条 todo 数据。

EditTodo.vue

<template>
  <Form onFinish={onFinish}>
    <!-- ... -->
  </Form>
</template>

<script setup>
import { useRequest, updateState } from 'alova';

const props = defineProps({
  id: Number
})

// 省略获取编辑数据的代码
const { send } = useRequest(updateTodo, {
  immediate: false
});

const onFinish = async form => {
  await send({
    ...form,
    id: props.id
  });

  // 使用方法实例更新对应状态
  updateState(getTodoList(), list => {    
    return list.map(item => {
      if(item.id === form.id) {
        return {...item, ...form};  
      }
      return item;
    });
  })
}
</script>

3. 新增Todo项

如果是新增一个todo项,那么上面的onFinish可以写成下面这样子

const onFinish = async form => {
  await send({
   ...form,
    id: props.id
  });

  // 使用方法实例更新对应状态
  updateState(getTodoList(), list => {    
    return [...list, form];
  });
}

这下通过 updateState 就可以轻松把列表状态更新过来了,没有全局状态那么复杂,也不用组件之间通知事件!

结尾

alova 也致力于解决客户端网络请求的问题,但与其他请求库不同的是,alova 选择了业务场景化请求策略的方向,它配合axios/fetch api等请求库后能满足你绝大部分请求需求(99%)的同时,还提供了丰富的高级功能。

  • 你可能曾经也在思考着应该封装fetchaxios,现在你不再需要这么做了,通过 alova 使用声明的方式完成请求,例如请求共享、分页请求、表单提交、断点上传等各种较复杂的请求,以及自动化缓存管理、请求共享、跨组件更新状态等。
  • alova 是轻量级的,只有 4kb+,是 axios 的 30%+。
  • 目前支持vue/react/react-native/svelte,以及next/nuxt/sveltekit等 SSR 框架,同时也支持Uniapp/Taro多端统一框架。
  • alova 是低耦合的,你可以通过不同的适配器让 alova 在任何 js 环境下,与任何 UI 框架协作使用(内置支持的 UI 框架为vue/react/svelte),并且提供了统一的使用体验和完美的代码迁移。
  • 使用 alova 还能实现 api 代码的高聚合组织方式,每个 api 的请求参数、缓存行为、响应数据转换等都将聚集在相同的代码块中,这对于管理大量的 api 有很大的优势。

与其他请求库的对比

强大的请求策略模块

alovajs 还提供了其他强大的请求策略:

名称描述文档
分页请求策略自动管理分页数据,数据预加载,减少不必要的数据刷新,流畅性提高 300%,编码难度降低 50%usePagination
无感数据交互策略全新的交互体验,提交即响应,大幅降低网络波动造成的影响,让你的应用在网络不稳定,甚至断网状态下依然可用useSQRequest
表单提交策略为表单提交而设计的 hook,通过此 hook 你可以很方便地实现表单草稿、多页面(多步骤)表单,除此以外还提供了表单重置等常用功能useForm
文件上传策略更简单的文件上传策略,支持对 base64、Blob、ArrayBuffer、Canvas 数据的自动识别和转换useUploader
发送验证码验证码发送 hook,减掉你在开发验证码发送功能时的繁琐。useCaptcha
自动重新拉取数据在一定条件下自动重新拉取数据,保证始终展示最新数据。useAutoRequest
跨组件触发请求一个 alova 中间件,消除组件层级的限制,在任意组件中快速地触发任意请求的操作函数actionDelegationMiddleware
串行请求的 useRequestalova 的串行请求方式更加简洁易用的串行请求 use hook,提供统一的 loading 状态、error、回调函数useSerialRequest
串行请求的 useWatcheralova 的串行请求方式更加简洁易用的串行请求 use hook,提供统一的 loading 状态、error、回调函数。useSerialWatcher
请求重试策略请求失败自动重试,它在重要的请求和轮询请求上发挥重要作用useRetriableRequest
SSE 请求通过 Server-sent Events 进行请求useSSE

想学习更多 alovajs 的用法,欢迎来alova 官网学习。如果你也喜欢 alovajs,请在Github 仓库中贡献一颗 star,这对我们非常重要。

如果觉得文章对你有帮助,请别吝啬你的赞和评论哈,说说你对 alovajs 怎么看的,或者可以问一些问题,我会尽量回答的,你的支持是我创作的最大动力!哈哈哈哈哈哈~

欢迎加入交流社区

有任何问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。

同时也欢迎贡献你的一份力量,请移步贡献指南

往期文章