vite-uni-dev-tool
Version:
vite-uni-dev-tool, debug, uni-app, 一处编写,到处调试
265 lines (225 loc) • 13.1 kB
Markdown
# useRequest
useRequest 是一个用于处理数据请求的 Vue 3 Composition API Hook
## 核心配置
| 配置项 | 类型 | 说明 |
| ------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| useUniLoading | boolean | 是否需要调用 uni.showLoading 显示加载提示,默认不开启 |
| ready | boolean\|\| Ref\<boolean\> | 请求触发前置条件:1. 当值从 false 变为 true 时,会自动发起请求 2. 当值为 false 时,请求永远不会被触发3. 支持普通布尔值或响应式布尔值(Ref`<boolean>`) |
| manual | boolean | 是否手动触发请求: 为 true 时,请求不会自动执行,需通过 run/runAsync 手动触发 为 false 时,满足前置条件后自动发起请求 |
| defaultParams | P | 请求默认参数,发起请求时会作为基础参数传入 注意:分页参数请放入 paginationConfig 中配置,不建议在此传入 |
| refreshDeps | any[] | 依赖刷新数组,当数组中的任意元素发生变化时,会自动重新发起请求,用于实现「依赖变更刷新数据」的场景 |
## 加载优化配置
| 配置项 | 类型 | 说明 |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| loadingDelay | number | 延迟结束加载提示的时间,单位为毫秒 作用:防止请求响应过快造成加载提示闪烁,提升用户体验,例如配置 300 表示加载提示至少显示 300 毫秒 |
## 轮询配置
| 配置项 | 类型 | 说明 |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------- |
| pollingInterval | number | 轮询间隔时间,单位为毫秒 使用规则:通过 run/runAsync 方法启动轮询,通过 cancel 方法取消轮询 |
| pollingErrorRetryCount | number | 轮询错误重试次数 作用:当轮询过程中请求失败时,会自动重试指定次数,重试失败后停止轮询 |
## 错误重试配置
| 配置项 | 类型 | 说明 |
| --------------- | ------ | ------------------------------------------------------------------------------------------- |
| errorRetryCount | number | 普通请求(非轮询)的错误重试次数 作用:当单次请求失败时,会自动重试指定次数,提升请求成功率 |
| errorRetryDelay | number | 错误重试间隔时间,单位为毫秒 作用:配置两次重试之间的等待时间,避免频繁重试给服务端造成压力 |
## 防抖配置
| 配置项 | 类型 | 说明 |
| ---------------- | ------- | ------------------------------------ |
| debounceWait | number | 防抖等待时间,单位为毫秒 |
| debounceLeading | boolean | 是否在防抖开始前执行调用(前置执行) |
| debounceTrailing | boolean | 是否在防抖结束后执行调用(后置执行) |
## 节流配置
| 配置项 | 类型 | 说明 |
| ---------------- | ------- | ------------------------------------ |
| throttleWait | number | 节流等待时间,单位为毫秒 |
| throttleLeading | boolean | 是否在节流开始前执行调用(前置执行) |
| throttleTrailing | boolean | 是否在节流结束后执行调用(后置执行) |
## 分页配置
| 配置项 | 类型 | 说明 |
| ---------------- | ------- | ------------------------------------------------------------------- |
| usePagination | boolean | 是否启用分页功能,启用后会自动整合分页参数和分页返回结果 |
| paginationConfig | Object | 分页详细配置对象,仅当 usePagination: true 时生效,具体子配置见下表 |
## paginationConfig 子配置
| 子配置项 | 类型 | 默认值 | 说明 |
| --------------- | ------ | ---------- | ---------------------------------------------------------------------------- |
| currentKey | string | 'current' | 后端接收的「当前页码」参数名,例如后端要求传 pageNum,则配置该值为 'pageNum' |
| pageSizeKey | string | 'pageSize' | 后端接收的「每页数量」参数名,例如后端要求传 size,则配置该值为 'size' |
| totalKey | string | 'total' | 后端返回结果中「总数据条数」的字段名,用于解析总页数 |
| defaultCurrent | number | 1 | 默认当前页码,初始化时的起始页码 |
| defaultPageSize | number | 10 | 默认每页显示数据条数,初始化时的每页数量 |
| listKey | string | 'list' | 后端返回结果中「分页数据列表」的字段名,用于解析分页数据集合 |
## 生命周期回调配置
| 配置项 | 类型 | 说明 |
| --------- | ------------------------------------------- | -------------------------------------------------------- |
| onBefore | () => Promise\<void\> \| void | 请求发起前的回调函数,支持同步和异步操作(返回 Promise) |
| onSuccess | (result: R\| undefined, params?: P) => void | 请求成功后的回调函数 |
| onError | (error: any) => void | 请求失败后的回调函数 |
| onFinally | () => void | 请求完成后的回调函数(无论成功或失败都会执行) |
## 返回结果
| 返回属性 | 类型说明 | 功能与使用说明 |
| ------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| data | R | 存储请求成功后的返回结果数据,初始化时为 undefined,请求成功后更新为后端返回的有效数据 |
| setData | (value: R\| undefined) => void | 手动设置 data 数据的方法,可用于手动更新返回结果缓存,例如手动重置数据、修改部分返回结果 |
| loading | boolean | 存储当前请求的加载状态 |
| setLoading | (value: boolean) => void | 手动设置 loading 加载状态的方法,可用于特殊场景下手动控制加载提示的显示与隐藏 |
| run | (params?: P) => void | 手动触发请求(同步风格),可传入可选参数 params 覆盖默认参数(defaultParams) |
| runAsync | (params?: P) => Promise\<R \| undefined\> | 手动触发请求(异步风格,返回 Promise),可传入可选参数 params 覆盖默认参数 |
| refresh | () => void | 刷新当前请求(同步风格),不支持传入新参数,沿用上次请求的参数重新发起请求,适用于「重新加载当前数据」的场景 |
| refreshAsync | () => Promise\<R \| undefined\> | 刷新当前请求(异步风格,返回 Promise),不支持传入新参数,沿用上次请求的参数重新发起请求 |
| cancel | () => void | 取消当前正在进行的请求 |
| pagination | Object | undefined 仅当 option.usePagination: true 时返回有效分页对象,否则为 undefined |
| list | array | 合并分页后的数据,建议current起始为1时使用该数据,防止数据不连续 |
## 使用示例
```ts
<template>
<view class="content">
<view>data:{{ data }}</view>
<view>loading:{{ loading }}</view>
<button @click="onTestRun">测试 run</button>
<button @click="onTestRunAsync">测试 runAsync</button>
<button @click="onTestRefresh">测试 refresh</button>
<button @click="onTestRefreshAsync">测试 refreshAsync</button>
<button @click="onTestRefreshDeps">测试 refreshDeps</button>
<button @click="onTestCancel">测试 cancel</button>
<button @click="onTestReady">测试 ready {{ ready }}</button>
<button @click="onTestDebounce">测试 debounce</button>
<button @click="onTestThrottle">测试 throttle</button>
<button @click="onTestPagination">测试分页</button>
</view>
</template>
<script lang="ts" setup>
import useRequest from '../../dev/v3/hooks/useRequest/index';
import { watch, ref } from 'vue';
const num = ref(0);
const ready = ref(false);
const {
data,
loading,
pagination,
run,
runAsync,
refresh,
refreshAsync,
cancel,
} = useRequest(
async (params: { a: number; b?: number }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve({
// a: 1,
// });
// reject(new Error('error'));
resolve({
current: 1,
pageSize: 10,
total: 100,
list: [
{ a: 1 },
{ a: 2 },
{ a: 3 },
{ a: 4 },
{ a: 5 },
{ a: 6 },
{ a: 7 },
{ a: 8 },
{ a: 9 },
{ a: 10 },
],
});
}, 1000);
});
},
{
// manual: true,
useUniLoading: true,
defaultParams: [
{
a: 1,
},
],
refreshDeps: [num],
// pollingInterval: 3 * 1000,
// pollingErrorRetryCount: 3,
// errorRetryCount: 3,
// errorRetryDelay: 3 * 1000,
// ready,
// debounceWait: 3 * 1000,
// debounceLeading: true,
throttleWait: 3 * 1000,
throttleLeading: true,
usePagination: true,
onBefore: () => {
console.log('before');
},
onSuccess: (result, params) => {
console.log('result', result);
console.log('params', params);
},
onError: (err) => {
console.log('err', err);
},
onFinally: () => {
console.log('finally');
},
},
);
watch(
data,
(val) => {
console.log('val', val);
},
{
immediate: true,
},
);
function onTestRun() {
run({ a: 1 });
}
async function onTestRunAsync() {
const res = await runAsync({ a: 1 });
console.log('onTestRunAsync: ', res);
}
function onTestRefresh() {
refresh();
}
async function onTestRefreshAsync() {
const res = await refreshAsync();
console.log('refreshAsync: ', res);
}
function onTestRefreshDeps() {
num.value++;
}
function onTestCancel() {
cancel();
}
function onTestReady() {
ready.value = !ready.value;
}
function onTestDebounce() {
console.log('onTestDebounce');
run({ a: 123 });
}
function onTestThrottle() {
console.log('onTestThrottle');
run({ a: 456 });
}
function onTestPagination() {
// run({ a: 1 }, { current: 1, pageSize: 10 });
pagination?.next();
console.log('pagination: ', pagination);
}
</script>
<style scoped>
.content {
padding: 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
}
button {
width: 100%;
}
</style>
```