GithubHelp home page GithubHelp logo

attojs / vue-request Goto Github PK

View Code? Open in Web Editor NEW
1.2K 12.0 84.0 1.87 MB

⚡️ This is a library that can easily help you manage request states, supporting common features such as SWR, polling, error retry, caching, and pagination, etc. ⚡️ 这是一个能够轻松帮助你管理请求状态的库,支持 SWR、轮询、错误重试、缓存、分页等常用功能。

Home Page: https://www.attojs.org

License: MIT License

JavaScript 1.99% TypeScript 97.89% Shell 0.11%
vue-request swr composition-api vue3 vue axios vuerequest userequest

vue-request's People

Contributors

benny-eu avatar bighippozz avatar dependabot[bot] avatar duncan-zjp avatar john60676 avatar qianphong avatar wxh16144 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-request's Issues

单文件组件中使用 queries 请求返回的数据需要通过 .value 获取

Bug 描述 Bug description

在vue单文件组件中使用 queries 请求返回的数据需要通过 .value 获取

    <span v-if="queries[i.id]?.loading.value">loading...</span>
    <span v-else> {{ queries[i.id]?.data.value }}</span>

代码重现 Reproduce

https://codesandbox.io/s/awesome-easley-nwydw?file=/src/App.vue

期望结果 Desired result

能直接通过queries[id].loadingqueries[id].data 获取数据

其他信息 Other information

[Feature Request] useLoadMore 支持不清空 dataList 从第一页重新加载数据

需求描述 Feature Description

useLoadMore 使用时,每次下拉刷新调用 reload 方法都会清空掉 dataList 数据重新加载,但是在大多数情况下,下拉刷新的操作数据其实不会变化,这样每次下拉刷新列表操作都会闪动一下(数据消失,接口调用成功之后再展示相同的内容),比较影响用户体验

建议的解决方案 Proposed Solution

建议新增一个 refresh 方法,覆盖掉现有的 refresh 方法用来做下拉刷新,该方法调用后,重新从第一页加载数据的同时不会清空掉 dataList 的内容,而是在接口调用成功之后直接替换掉 dataList 的原有内容

无法正确的拿到data值

Bug 描述 Bug description

打印data为undefined

代码重现 Reproduce

const { data, loading } = useRequest(APICESHI);
console.log(data.value);

期望结果 Desired result

可以拿到data的值

其他信息 Other information

[Need Help]请问如何使data正确显示经过formatResult处理过的ts类型

我继承并重写了axios.get方法,使他返回类型如下
image
image
在调用业务接口的时候如下使用
image
findDataSetListByUserId4Select现在返回的类型是我期待的Promis<BusinessResponseData<(SelfDataSetPreviewParams | SqlDataSetPreviewParams)[]>>这些没有问题
vuerequest全局配置如下
image
在vue组件中这样使用
image
我希望data的类型应该是经过formatResult转换过的(SelfDataSetPreviewParams | SqlDataSetPreviewParams)[]但实际上他是BusinessResponseData<(SelfDataSetPreviewParams | SqlDataSetPreviewParams)[]>,请问怎么能让data的类型正确显示为(SelfDataSetPreviewParams | SqlDataSetPreviewParams)[]

Support Pagination

Usage

import { usePagination } from 'vue-request';

API

Property Description Type Default
current current page number number 1
pageSize number of data items per page number 10
total total number of data items number 0
totalPage total number of pages number -
onChange a callback function, executed when changeCurrent or changePageSize is called (current: number, pageSize: number) => void -
changeCurrent change current page (current: number) => void -
changePageSize change pageSize (pageSize: number) => void -

@adiramardiani

@adiramardiani

Sorry, I have been busy lately, so I only reply to your question now.

The last piece of code is correct

const { data: dataSource, run, current, total, loading, pageSize } = usePagination(repo.queryData, {
    // remove one data
    formatResult: res => res.data.data,
    pagination: {
        currentKey: 'page',
        pageSizeKey: 'per_page',
        totalKey: 'total',
    },
})

The problem of dataSource, you can use dataSource.value.data to get data

Originally posted by @John60676 in #51 (comment)

Error Retries 功能讨论

  • errorRetryCount 错误重试次数
  • errorRetryInterval 多次错误重试的间隔时间

待讨论问题

  • 当请求设置了轮询 pollingInterval ,Error Retries 是否能够同时开启?如果上述成立,轮询时发生错误,是否交由 Error Retries 来处理,待重试次数耗尽,轮询将结束?
  • 当请求设置了 throwOnError,Error Retries 是否能够同时开启?
  • errorRetryCount应该在何时重置,除了请求成功能够重置外,用户手动触发,例如 run refresh 这类API时是否也应该重置?

Add hooks before and after request

Usage

const request = useRequest(server, {
  onBefore(params) {},
  onAfter(params) {},
})

API

Options

Property Description Type Default
onBefore Hook before request (params: P) => void -
onAfter Hook after request (params: P) => void -

Add `reloading` to record the loading status of `reload`

Usage

const { reloading } = useRequest(server, options)

const { reloading } = usePagination(server, options)

const { reloading } = useLoadMore(server, options)

API

Return Values

Property Description Type Default
reloading loading status of reload Boolean false

Support `Load More` plugins

Usage

import { useLoadMore } from 'vue-request';

API

Return Values

Property Description Type Default
dataList data set LR []
loadMore trigger to load more () => void -
loadingMore is loading more boolean false
noMore whether there is more data depends on the result of isNoMore boolean -
reload clear and reload list () => void -

Options

Property Description Type Default
isNoMore determine if there is more data (data:R) => boolean -
listKey the path of the data set string -

usePagination 设置每页记录数问题

请问 usePagination 怎么才能设置返回的每页记录数呢?如果我用 usePagination返回的changePageSize设置为 changePageSize(20) 这样设置,第一次进入页面时,要访问两次服务器,第一次是https://randomuser.me/api?noinfo&results=10&page=1,第二次是 https://randomuser.me/api?noinfo&results=20&page=1,只有翻页时,才会执行一次,即https://randomuser.me/api?noinfo&results=20&page=2
是我用的不对吗?

项目打包类型引入报错

Bug 描述 Bug description

vue-request 更新到 1.2.2,项目打包提示如下错误

20211012104035

20211012104045

20211012104049

代码重现 Reproduce

期望结果 Desired result

src/core/types.ts 使用相对路径引入类型

- import type { LoadMoreExtendsOption } from 'src/useLoadMore';
- import type { PaginationExtendsOption } from 'src/usePagination';

+ import type { LoadMoreExtendsOption } from '../useLoadMore';
+ import type { PaginationExtendsOption } from '../usePagination';

其他信息 Other information

typescript文件报错

Bug 描述 Bug description

检测项目ts类型报错

代码重现 Reproduce

571616385402_ pic

期望结果 Desired result

不报错

其他信息 Other information

添加一个 RequestConfig 组件

Motivation

使用 provideinject 实现 局部全局 的效果,使得同一 context 共用一份配置

Usage

<RequestConfig
  config={{
    loadingDelay: 300,
    pollingInterval: 1000,
    // ...
  }}
>
  <Child />
</RequestConfig>

Detailed design

  • 配置的读取顺序应该为
    • 当前调用时传入的配置 > RequestConfig > setGlobalConfig
  • providerejectkey,应该为 Symbol

[Need Help]依赖请求无法获取被依赖请求的返回值

// *.vue -script
import { useRequest } from 'vue-request'
import { findDataVisualById, getVisualResult } from '@/api'
import { computed, unref } from 'vue'

const props = defineProps<{
  visualId: string
}>()

// 请求A
const { data: visualConf } = useRequest(findDataVisualById, {
  defaultParams: [{ id: props.visualId }],
  manual: false,
  formatResult: res => res.data
})
// 请求B
const { data: visualData } = useRequest(getVisualResult, {
  ready: computed(() => !!visualConf.value),
  defaultParams: [visualConf.value!],
  manual: false,
  formatResult: res => res.data
})

如上,需求是请求A完成后请求B以A的返回值作为入参发起请求,时间控制是没问题的,但是请求B拿不到A的返回值,思考原因是B的defaultParams绑定的是visualConf.value,这不是一个响应式的值,导致visualConf更新时visualConf.value不能响应更新,并且defaultParams不能直接绑定visualConf ,请问如何在不手动调用B的run方法情况下能够拿到A的返回值作为默认参数并发起请求

[Need Help]

问题描述 Problem Description

分页功能在setup函数内自动第一次获取数据,得到current是0,不是文档中的1。

其他信息 Other information

🤣🤣🤣 代码优化

generateService.ts文件这样写感觉能够简洁一点

const generateService = <D, P extends unknown[]>(
  service: IService<D, P>
): (() => Promise<D>) | ((...args: P) => Promise<D>) => {
  return async function (...args: P) {
    if (isFunction(service)) {
      return generateService(service(...args))();
    } else if (isPromise(service)) {
      return service;
    } else if (isString(service)) {
      return requestProxy(service);
    } else if (isPlainObject(service)) {
      const { url, ...rest } = service;
      return requestProxy(url, rest);
    } else {
      throw new Error(" unknown  service type  ");
    }
  };
};

export default generateService;

[Need Help] Get total data from laravel api with axios

Problem Description

Hi, I'm come here because I'm currently using antdv2 for component table with pagination, and documentation refer your library, after I read your documentation it turns out that you also refer antdv2 for the example :D

As explained in the title, I have a need for a component that can fetch data from laravel pagination, everything works fine when I run the documentation from ant regarding table components and ajax, but I'm stuck because documentation write hardcode for total

const pagination = computed(() => ({
      total: 200, //I need this dynamic, also get from api
      current: current.value,
      pageSize: pageSize.value,
}));

I use this from laravel

$result['data'] = Model::paginate($per_page);

And give this json result

{
  "current_page": 1,
  "data": [
   ...
    {
      "id": x,
      "name": "name",
      ...
    },
    ...
  ],
  ...
  "per_page": "10",
  "prev_page_url": null,
  "to": 10,
  "total": 200
}

I use axios to fetch api because it's good and your recomendation, so I write this on some file :

import api from 'axios'
export default {
    async queryData(data) {
        return await api.get(`/users`,{ params: data })
    },
}

And this is my table component:

const { data: dataSource, run, loading, current, total, pageSize } = usePagination(repo.queryData, {
      //response.data : axios return .data for access api data
      //.data : laravel return data when use json return
      //.data : data from my code like I describe above
      // yes so many data, but currently this is my standard, if this change will affect to other :p
      formatResult: res => res.data.data.data,
      pagination: {
        currentKey: 'page',
        pageSizeKey: 'per_page',
      },
});
const pagination = computed(() => ({
      total: 200,
      current: current.value,
      pageSize: pageSize.value,
}));
...

this is work perfectly, but when when I use dynamic from total

const pagination = computed(() => ({
      total: tota.value,
      current: current.value,
      pageSize: pageSize.value,
}));

this is not working because, total.value give 0. I change code like this

const { data: dataSource, run, current, total, loading, pageSize } = usePagination(repo.queryData, {
           // remove one data
            formatResult: res => res.data.data,
            pagination: {
                currentKey: 'page',
                pageSizeKey: 'per_page',
                totalKey: 'total',
            },
})

this is catch total perfectly, but datasource now error, can you help me ?

[Feature Request]

需求描述 Feature Description

希望 run 返回 Promise,现在无论执行成功与否都会走到 then

比如批量删除和删除使用同一个请求,但返回后触发不同操作,不适用 onSuccess

建议的解决方案 Proposed Solution

run({}).then(res => {
  // do something
}).catch(err => {})

其他信息 Other information

关于文档

问题描述 Problem Description

文档的改进

首先感谢作者创建了这么好的仓库。
但是我发现在文档的示例中偏少了一点,如果能更完善一点就更好了

其他信息 Other information

onSuccess方法的入参data无法获取正确的type

Bug 描述 Bug description

onSuccess方法的入参data无法获取正确的type

代码重现 Reproduce

531615877457_ pic_hd
541615877516_ pic_hd
551615877742_ pic

期望结果 Desired result

onSuccess方法的入参data可以获取正确的type

其他信息 Other information

[Need Help] 在路由生命周期 beforeRouteEnter 钩子内部是否可以使用 useRequest ?

问题描述 Problem Description

我希望在 beforeRouteEnter 钩子里面调用接口获取数据,然后在拿到数据字后调用 next 方法,拿到 vm 实例将数据交给 vm 直接渲染。是否可以在 beforeRouteEnter 钩子里面使用 useRequest 方法呢?

我看到源码里面有使用到 watch watchEffect 这样的函数,这样的函数在 setup 函数之外调用是否会有意外发生。我担心 watchEffect 在 setup 之外使用无法正常停止侦听。

请问在usePagination中是不能用queryKey

问题描述 Problem Description

在列表上执行更新或者删除时常用queryKey来维护loading状态等。但现在有一个这样的场景,在使用可嵌套表格时,在点击展开时来加载子表格的数据,此时要维护不同的子表格请求状态例如loading等,但usePagination好像不支持qureyKey

其他信息 Other information

1630919897(1)

[Bug Report] 分页功能的antd示例在编辑器中报错

`

<a-table
:columns="columns"
:row-key="record => record.login.uuid"
:data-source="dataSource"
:pagination="pagination"
:loading="loading"
@change="handleTableChange"

<template #name="{ text }">{{ text.first }} {{ text.last }}</template>
<script lang="ts"> import { TableState, TableStateFilters } from 'ant-design-vue/es/table/interface' import { usePagination } from 'vue-request' import { computed, defineComponent } from 'vue'

const columns = [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
width: '20%',
slots: { customRender: 'name' }
},
{
title: 'Gender',
dataIndex: 'gender',
filters: [
{
text: 'Male',
value: 'male'
},
{
text: 'Female',
value: 'female'
}
],
width: '20%'
},
{
title: 'Email',
dataIndex: 'email'
}
]

type Pagination = TableState['pagination'];
type APIParams = {
results: number;
page?: number;
sortField?: string;
sortOrder?: number;
[key: string]: any;
};
type APIResult = {
results: {
gender: 'female' | 'male';
name: string;
email: string;
}[];
};

const queryData = (params: APIParams) => {
return https://randomuser.me/api?noinfo&${new URLSearchParams(params)}
}

export default defineComponent({
setup () {
const {
data: dataSource,
run,
loading,
current,
pageSize
} = usePagination(
queryData,
{
formatResult: res => res.results,
pagination: {
currentKey: 'page',
pageSizeKey: 'results'
}
}
)

const pagination = computed(() => ({
  total: 200,
  current: current.value,
  pageSize: pageSize.value
}))

const handleTableChange = (pag: Pagination, filters: TableStateFilters, sorter: any) => {
  run({
    results: pag!.pageSize!,
    page: pag?.current,
    sortField: sorter.field,
    sortOrder: sorter.order,
    ...filters
  })
}

return {
  dataSource,
  pagination,
  loading,
  columns,
  handleTableChange
}

}
})
</script>
`

https://2x.antdv.com/components/table-cn#components-table-demo-ajax
image

[Bug Report] usePagination manual 为 true 时,defaultParams: [{ pageSize: 50 }] 无效

Bug 描述 Bug description

manual: true 时设置的defaultParams: [{ pageSizeKey: 50 }]不生效,获取到的 pageSize 为10

代码重现 Reproduce

      const {
        current,
        total,
        loading,
        pageSize,
        changeCurrent,
        changePageSize,
        run: fetchData,
      } = usePagination(fetchOrderList, {
        // manual: true,
        defaultParams: [{ pageSize: 50, page: 1 }],
        pagination: { currentKey: 'page', pageSizeKey: 'pageSize', totalKey: 'total' },
        onSuccess: (res) => {
          gridOptions.value.api?.setRowData(res.data);
        },
      });

期望结果 Desired result

获得的 pageSize 默认为 50

其他信息 Other information

v1需求

参考 useRequest

基础 API

  • 默认请求

  • 手动触发

  • 轮询

  • 并行请求

  • 依赖请求

  • 防抖

  • 节流

  • 缓存 & SWR

  • 预加载

  • 屏幕聚焦重新请求

  • 突变

  • Loading Delay

  • refreshDeps

  • 全局配置

[Need Help] usePagination 如何同时修改 current 和 pageSize

问题描述 Problem Description

当需要同时改变 currentpageSize 时是不是应该只发起一次请求?

场景

image

当如上图的页码,切换为 200条/页 时,分页器会将 页码切换到可用的最后一页 如下

image

为了保证数据可用,不管是使用分页器的方案还是自己重新计算下可用页码都需要同时调用 changeCurrentchangePageSize,此时会触发两次请求

其他信息 Other information

[Bug Report] useLoadMore not returning dataList

here is my code

const { dataList, loading, loadingMore, loadMore } = useLoadMore( getStratData, {
        listKey: 'results',
        onSuccess: (res) => {
            console.log("22222--2-2>", res.data.length)
        }
    })

return {
      ...toRefs(state),
      dataList,
      loadMore
    }

but dataList is empty in my template.

import error.

Version

vue:3.0.4
** vue-request:1.0.0-beta.4**

Reproduce

引入时报错

import {useRequest} from 'vue-request';

错误信息:

Module parse failed: Unexpected token (14:33)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   setup(props, { slots }) {
|
>       return () => slots.default?.();
|   },
| });

为什么debounce,throttle,不考虑加入options呢?

lodash,是提供了这两个参数的,可以更灵活控制,看源码似乎,添加这样的参数并没有产生bug影响。故请教一下原因

[options.leading=true] (boolean): 指定调用在节流开始前。
[options.trailing=true] (boolean): 指定调用在节流结束后。

在使用 vue-request 之后的一些改进建议

最近我们做了个新项目选用了 vue3,也使用了 vue-request 这个库,目前使用一个多月了,有一些建议我觉得可以讨论一下

暴露更多的内部 API和类型

目前我们项目使用这个库,都是无法直接使用的,需要进行二次封装,这个因为发送请求的多变性而没办法避免的,进行二次封装的时候我遇到了一些问题,有下面一些建议。

  1. 把一些类型声名 例如 BaseOption 这种在 index.ts 里面暴露出来,方便引入
  2. 把尽可能多的常量(例如QUERY_DEFAULT_KEY),内部方法(例如useAsyncQuery)在 index.ts 中暴露出来,方便自己实现一些自定义的逻辑
  3. 提供一些全局的 hooks 用于实现一些自定义的逻辑,例如只要有一个请求变为 loading 的时候,触发一个比如叫 beforeAnyLoading 的钩子,所有请求都加载完触发一个 afterAllLoaded 钩子,可以很方便的实现一些例如

说实话我感觉用这个库的时候,二次封装的可能性非常大,我觉得作者大大可以多考虑一下二次封装的便捷性。

---------------------------分割线,下面可能是一些废话,作者大大可以考虑跳过,主要结论都在上面--------------------------

useRequest 的封装

我希望在发送请求的时候,如果请求时间过长超过 loadingDelay 的值的时候,在全局显示一个加载,遇到我问题如下

  1. 我需要对 useRequest 的第二个参数进行扩展,例如再传入一个参数用于设置 loading 的提示语,那么需要把例如 BaseOptions进行扩展,但是导入的时候,我得从 vue-request/dist/types/core/config 里面进行导入,这很不友好。希望可以在 index.ts 直接导出
  2. 我无法再 loading 变为 true 之前和 loading 变为 false 之前做一些操作,目前我只能使用 watchEffect 来监听 loading 的变化来实现这个功能。

useLoadMore 的封装

因为加载更多这个逻辑,一个系统的类型肯定是一样的,如果不进行二次封装,那么每次使用的时候都会写一大堆类型声明,这样肯定不合适。二次封装的时候一些问题如下

  1. 导入类型太麻烦(x2 [手动狗头.png]),上面已经提到了
  2. formatResult 这个东西类型推导有问题,我二次封装的时候直接把这个功能砍掉了。而且我觉得这个功能意义不大,format 这个操作完全可以放到传入的 service 方法里面来做,不知道作者有没有其他的考虑[手动狗头.png]。
  3. loadingMore 在 reload 的时候是 false,这样的话就 reload 的时候,van-list 就没有 loading 动画了,所以就自己撸了一个,从而引出了下面一系列问题。(因为项目上线在即没办法和作者大大讨论再改,也不想给作者大大压力,咱们自己的需求还是自己解决,不过接口都是一样的,要是作者大大后续考虑支持的话,我直接把内部实现换成作者大大的 useLoadMore 就好了)

-----------下面是自己封装 useLoadMore 出现的问题----------

  1. 因为作者大大没有暴露 useAsyncQuery,所以就只能基于 useRequest 了(强烈建议多暴露一写内部方法)
  2. 开始一切顺利,不过在 reload 方法的时候,需要对数据重置,直接对 useRequest 返回值解构出来的 data 进行复制为 null 是不起作用的(看了源码发现 data 的值总是 latestQuery.value.data,赋值还是会被改回来),然后看到好像有个 reset 但是发现 useRequest 这个方法没导出 reset,然后想通过 queries 重置发现 QUERY_DEFAULT_KEY 这个常量没导出,最后我直接用 __QUERY_DEFAULT_KEY__ 这个玩意儿来获取默认 query,调用 mutate 来重置了。(饶了好大一个弯儿)。
  3. 如果暴露出 useAsyncQuery,上面那一步的东西都不存在

hooks 的设想

对于发送请求这个需求,应该会有很多的奇奇怪怪的需求,如果可以抽象出来一些公用的 hooks,应该可以解决很多自定义的需求,例如上面我对 useRequest 进行封装,在请求超过 loadingDelay 的时候,全局显示 loading,如果有一个 hook,只要有一个请求变为 loading 的时候,触发一个比如叫 beforeAnyLoading 的钩子,然后我就给他显示一个 loading 动画,然后有个 afterAllLoaded,然后我把 loading 动画关掉,这就很完美。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.