Skip to content

Commit

Permalink
feat: v2 (#196)
Browse files Browse the repository at this point in the history
* type: format result type

* type: sync

* type: format result type

* chore: upgrade v2

* feat: upgrade use-request plugin

* docs: add use-request format result docs

* docs: add migrate v2

* docs: opt

* docs: demo

* docs: add route

* test: use-request plugin unit test
  • Loading branch information
NelsonYong authored May 12, 2024
1 parent 6e59ff7 commit 2eb30fd
Show file tree
Hide file tree
Showing 33 changed files with 490 additions and 153 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
"@vue-hooks-plus/vitepress-demo-block": "workspace:^1.0.0",
"@vue-hooks-plus/use-immer":"workspace:^1.0.0",
"@vue-hooks-plus/use-worker":"workspace:^1.0.0",
"@vue-hooks-plus/use-request":"workspace:^1.0.0",
"@vue-hooks-plus/use-request-plugins":"workspace:^1.0.0",
"@vue-hooks-plus/types":"workspace:^1.0.0",
"@vue-hooks-plus/use-request":"workspace:^2.0.0",
"@vue-hooks-plus/use-request-plugins":"workspace:^2.0.0",
"@vue-hooks-plus/types":"workspace:^2.0.0",
"@vue-hooks-plus/eslint-config":"workspace:^1.0.0",
"@vue/test-utils": "^2.1.0",
"@vitest/coverage-c8":"^0.25.7",
Expand Down
19 changes: 15 additions & 4 deletions packages/hooks/docs/.vitepress/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ const useRequestRouter = [
text: '错误重试',
link: '/useRequest/retry/',
},

{
text: '格式化数据',
link: '/useRequest/formatResult/',
},
{
text: '缓存 & SWR',
link: '/useRequest/cache/',
Expand All @@ -155,7 +158,7 @@ const useRequestRouter = [
link: '/useRequest/scroll/',
},
{
text: '中间件·Beta',
text: '中间件',
link: '/useRequest/middleware/',
},
{
Expand Down Expand Up @@ -250,7 +253,10 @@ const useRequestRouterEN = [
text: 'Retry',
link: '/en/useRequest/retry/',
},

{
text: 'Format Result',
link: '/en/useRequest/formatResult/',
},
{
text: 'Cache & SWR',
link: '/en/useRequest/cache/',
Expand All @@ -268,7 +274,7 @@ const useRequestRouterEN = [
link: '/en/useRequest/scroll/',
},
{
text: 'Middleware·Beta',
text: 'Middleware',
link: '/en/useRequest/middleware/',
},
{
Expand Down Expand Up @@ -310,6 +316,11 @@ export function getRouterConfig(langPrefix = '/') {
text: langPrefix === '/' ? '📐 UseRequest规范' : '📐 UseRequest specification',
link: `${langPrefix}useRequest/guide/`,
},
{
text: langPrefix === '/' ? '🫶 迁移到 v2 版本' : '🫶 Migrate to v2 version',
link: `${langPrefix}migrate/`,
},

// {
// text: langPrefix === '/' ? '🧑‍🏫 在线教程' : '🧑‍🏫 Online Teaching',
// link: `${langPrefix}onlineTeaching/`,
Expand Down
41 changes: 41 additions & 0 deletions packages/hooks/docs/migrate/index.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 🫶 Migrate to v2 version

:::info

- useRequest plugin option

:::

## 1、useRequest plugin option

In order to have good type hints and subsequent expansion in the v2 version of useRequest plug-in system, we have redesigned the usage of plugin option. You only need to make simple changes to achieve migration.

## v1 use

```typescript
const { data } = useRequest(
() => serviceFn(),
{
...option,
...pluginOption,
},
[useFormatterPlugin, ...otherPlugins],
)
```

## v2 use

```typescript
const { data } = useRequest(
() => serviceFn(),
{
...option,
pluginOptions: {
...pluginOption,
},
},
[useFormatterPlugin, ...otherPlugins],
)
```

Just migrate it to `pluginOptions` based on the original plugin option.
41 changes: 41 additions & 0 deletions packages/hooks/docs/migrate/index.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 🫶 迁移到 v2 版本

:::info

- useRequest plugin option

:::

## 1、useRequest plugin option

v2 版本的 useRequest 插件系统为了有良好的类型提示以及后续拓展,我们重新设计了 plugin option 的使用方式,你只需要进行简单的改变即可达到迁移。

## v1 use

```typescript
const { data } = useRequest(
() => serviceFn(),
{
...option,
...pluginOption,
},
[useFormatterPlugin, ...otherPlugins],
)
```

## v2 use

```typescript
const { data } = useRequest(
() => serviceFn(),
{
...option,
pluginOptions: {
...pluginOption,
},
},
[useFormatterPlugin, ...otherPlugins],
)
```

只需要在原来的 plugin option 的基础上,将其迁移到 `pluginOptions` 下即可。
2 changes: 1 addition & 1 deletion packages/hooks/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-hooks-plus",
"version": "1.9.0",
"version": "2.0.0",
"description": "Vue hooks library",
"files": [
"dist",
Expand Down
11 changes: 6 additions & 5 deletions packages/hooks/src/useRequest/Fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
UseRequestOptions,
UseRequestPluginReturn,
UseRequestService,
UseRequestOptionsWithFormatResult
} from './types'

export default class Fetch<TData, TParams extends unknown[] = any> {
Expand All @@ -23,7 +24,7 @@ export default class Fetch<TData, TParams extends unknown[] = any> {

constructor(
public serviceRef: Ref<UseRequestService<TData, TParams>>,
public options: UseRequestOptions<TData, TParams, any>,
public options: Partial<UseRequestOptions<TData, TParams, any> & UseRequestOptionsWithFormatResult<TData, TParams, any, any>>,
public setUpdateData: (
currentState: unknown,
key?: keyof UseRequestFetchState<TData, TParams>,
Expand Down Expand Up @@ -116,7 +117,7 @@ export default class Fetch<TData, TParams extends unknown[] = any> {
)
// Do you want to stop the request
if (stopNow) {
return new Promise(() => {})
return new Promise(() => { })
}

this.setState({
Expand Down Expand Up @@ -144,7 +145,7 @@ export default class Fetch<TData, TParams extends unknown[] = any> {
this.runPluginHandler('onError', error, params)

// Manually intercept the error and return a Promise with an empty status
return new Promise(() => {})
return new Promise(() => { })
}

try {
Expand All @@ -154,7 +155,7 @@ export default class Fetch<TData, TParams extends unknown[] = any> {
const requestReturnResponse = (res: any) => {
// The request has been cancelled, and the count will be inconsistent with the currentCount
if (currentCount !== this.count) {
return new Promise(() => {})
return new Promise(() => { })
}
// Format data
const formattedResult = this.options.formatResult ? this.options.formatResult(res) : res
Expand Down Expand Up @@ -188,7 +189,7 @@ export default class Fetch<TData, TParams extends unknown[] = any> {
return requestReturnResponse(servicePromiseResult)
} catch (error) {
if (currentCount !== this.count) {
return new Promise(() => {})
return new Promise(() => { })
}

this.setState({
Expand Down
18 changes: 10 additions & 8 deletions packages/hooks/src/useRequest/__tests__/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const useFormatterPlugin: UseRequestPlugin<
{
formatter?: (params?: { name: string; age: number }) => any
}
> = (fetchInstance, { formatter }) => {
> = (fetchInstance, { pluginOptions }) => {
return {
onSuccess: () => {
fetchInstance.setData(formatter?.(fetchInstance.state.data), 'data')
fetchInstance.setData(pluginOptions?.formatter?.(fetchInstance.state.data), 'data')
},
}
}
Expand All @@ -37,12 +37,14 @@ describe('useRequest/Plugin', () => {
useRequest(
() => getUsername(),
{
formatter: (data: any) => {
return {
name: `${data.name} - plugins update`,
age: 20,
}
},
pluginOptions: {
formatter: (data) => {
return {
name: `${data?.name} - plugins update`,
age: 20,
}
},
}
},
[useFormatterPlugin],
),
Expand Down
6 changes: 3 additions & 3 deletions packages/hooks/src/useRequest/devtools/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { setupDevtoolsPlugin } from '@vue/devtools-api'

import { unref } from 'vue'
import { getRequestTagBg } from './utils'
import devToolsStore from './store'
import Fetch from '../Fetch'
import { unref } from 'vue'

const pluginId = 'vue-hooks-plus'
const pluginName = 'Vue Hooks Plus 🍭'
Expand Down Expand Up @@ -163,11 +163,11 @@ export function setupDevtools(app: any) {
'Data Explorer': Object.keys(currentSource.instance.state).map(item => ({
key: item,
value:
currentSource.instance.state[item as keyof typeof currentSource.instance.state],
unref(currentSource.instance.state[item as keyof typeof currentSource.instance.state]),
})),
Option: Object.keys(currentSource.instance.options).map(item => ({
key: item,
value: unref(currentSource.instance.options[item]),
value: currentSource.instance.options[item as keyof typeof currentSource.instance.options],
})),
["Plugins 🧩"]:
currentSource.instance.pluginImpls?.map((_, index) => {
Expand Down
10 changes: 2 additions & 8 deletions packages/hooks/src/useRequest/docs/basic/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ In the following example, we demonstrate a scenario of `mutate`.

We have modified the user name, but we do not want to wait for the request to be successful before giving feedback to the user. Instead, modify the data directly, then call the modify request in background, and provide additional feedback after the request returns.

### error rollback `1.7.7.alpha.4`
### error rollback

When you use `mutate`, it is possible that the remote data change fails after the optimistic data is displayed to the user. In this case, you can enable `rollbackOnError`, which restores the local cache to its previous state, ensuring that the user sees Got the correct data.

Expand Down Expand Up @@ -149,12 +149,6 @@ If we set `options.manual = false`, the parameters of calling `service` for the
title=""
desc=""> </demo>

## Format the request data

Since `useRequest` needs to guarantee a good plug-in system, format is too invasive for the system, the formatting here is `useFormatResult`, format data to `useFormatResult` after the request data is completed, `useFormatResult` can well support `typescript` type prompt. <br />

<a href="/docs/hooks/en/useFormatResult/" >Jump to useFormatResult</a>

## API

```ts
Expand Down Expand Up @@ -205,7 +199,7 @@ const {
| initialData | Init data | `TData` \| `undefined` |
| manual | <ul><li> The default is `false`. That is, the service is automatically executed during initialization.</li><li>If set to `true`, you need to manually call `run` or `runAsync` to trigger execution. </li></ul> | `boolean` | `false` |
| defaultParams | The parameters passed to the service at the first default execution | `TParams` | - |
| formatResult | Format the request results, which recommend to use `useFormatResult` | `(response: TData) => any` | - |
| formatResult | Format the request results,v1 which recommend to use `useFormatResult` | `(response: TData) => FormatData` | - |
| onBefore | Triggered before service execution | `(params: TParams) => void` | - |
| onSuccess | Triggered when service resolve | `(data: TData, params: TParams) => void` | - |
| onError | Triggered when service reject | `(e: Error, params: TParams) => void` | - |
Expand Down
8 changes: 1 addition & 7 deletions packages/hooks/src/useRequest/docs/basic/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,6 @@ runAsync()
title=""
desc=""> </demo>

## 格式化请求数据

由于 `useRequest` 需要保证良好的插件系统,format 对于系统来说侵入性太大,这里格式化使用的的是 `useFormatResult`,在请求数据完成后将 data 传入 `useFormatResult` 进行格式化, `useFormatResult` 可以很好的支持 `typescript` 类型提示。 <br />

<a href="/docs/hooks/useFormatResult/" >跳转至 useFormatResult</a>

## API

```ts
Expand Down Expand Up @@ -202,7 +196,7 @@ const {
| initialData | 初始化的数据 | `TData` \| `undefined` |
| manual | <ul><li> 默认 `false`。 即在初始化时自动执行 service。</li><li>如果设置为 `true`,则需要手动调用 `run``runAsync` 触发执行。 </li></ul> | `boolean` | `false` |
| defaultParams | 首次默认执行时,传递给 service 的参数 | `TParams` | - |
| formatResult | 格式化请求结果,建议使用 `useFormatResult` | `(response: TData) => any` | - |
| formatResult | 格式化请求结果,v1 建议使用 `useFormatResult` | `(response: TData) => FormatData` | - |
| onBefore | service 执行前触发 | `(params: TParams) => void` | - |
| onSuccess | service resolve 时触发 | `(data: TData, params: TParams) => void` | - |
| onError | service reject 时触发 | `(e: Error, params: TParams) => void` | - |
Expand Down
27 changes: 27 additions & 0 deletions packages/hooks/src/useRequest/docs/formatResult/demo/demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<div>Origin name: {{ loading ? 'loading' : data }}</div>
<div>Format: {{ loading1 ? 'loading' : JSON.stringify(formatData) }}</div>
</template>

<script lang="ts" setup>
import { useRequest } from 'vue-hooks-plus'
function getUsername(params: { desc: string }): Promise<string> {
return new Promise(resolve => {
setTimeout(() => {
resolve(`vue-hooks-plus ${params.desc}`)
}, 1000)
})
}
const { data, loading } = useRequest(() => getUsername({ desc: 'good' }))
const { data: formatData, loading: loading1 } = useRequest(() => getUsername({ desc: 'good' }), {
formatResult(res) {
return {
name: `formatter ${res}`,
age: 18,
}
},
})
</script>
30 changes: 30 additions & 0 deletions packages/hooks/src/useRequest/docs/formatResult/index.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
map:
# 映射到docs的路径
path: /useRequest/formatResult/
source:
show: false
---

# Format the request result

## v1 use

Since v1 version `useRequest` needs to guarantee a good plug-in system, format is too invasive for the system, the formatting here is `useFormatResult`, format data to `useFormatResult` after the request data is completed, `useFormatResult` can well support `typescript` type prompt. <br />

<a href="/docs/hooks/en/useFormatResult/" >Jump to useFormatResult</a>

## v2 use

It now supports ts types very well.

<demo src="./demo/demo.vue"
language="vue"
title=""
desc="format the request result"> </demo>

## Options

| Property | Description | Type | Default |
| ------------ | ------------------------- | --------------------------------- | ------- |
| formatResult | format the request result | `(response: TData) => FormatData` | - |
Loading

0 comments on commit 2eb30fd

Please sign in to comment.