diff --git a/README.md b/README.md index 16bfbd6..03f9bf8 100644 --- a/README.md +++ b/README.md @@ -301,7 +301,14 @@ const useAxle = createUseAxle({ onTransform: (response) => response, }) -const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort, resetValue }] = useAxle({ +const [ + // response data + users, + // request runner/invoker + getUsers, + // extra properties + { loading, error, uploadProgress, downloadProgress, abort, resetValue } +] = useAxle({ // Request initial value value: [], // Request method @@ -407,7 +414,7 @@ function sendAllRequest() { ``` -### Enhancement +### API Definition Enhancement `createApi` is supported since `v0.9.0`, which is used to define APIs. @@ -494,3 +501,57 @@ async function handleDelete(id: string) { } } ``` + +### Runner Enhancement + +Since `v0.10.0`, the `runner` will include all the extra properties, so we can further simplify the work. + +before: + +```html + + + +``` + +after: + +```html + + + +``` diff --git a/README.zh-CN.md b/README.zh-CN.md index 7fe9bc7..507a4f0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -301,7 +301,14 @@ const useAxle = createUseAxle({ onTransform: (response) => response, }) -const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort }] = useAxle({ +const [ + // 请求数据 + users, + // 请求触发器 + getUsers, + // 附加属性 + { loading, error, uploadProgress, downloadProgress, abort } +] = useAxle({ // 请求初始化数据 value: [], // 请求方法 @@ -407,7 +414,7 @@ function sendAllRequest() { ``` -### 增强 +### API 定义增强 从 `0.9.0` 开始支持 `createApi`,以增强 API 定义能力。 @@ -494,3 +501,57 @@ async function handleDelete(id: string) { } } ``` + +### 请求触发器增强 + +从 `v0.10.0` 开始, 请求触发器将包含附加属性中的全部属性。 + +增强前: + +```html + + + +``` + +增强后: + +```html + + + +``` diff --git a/packages/axle/src/use.ts b/packages/axle/src/use.ts index 7401e03..55e62e4 100644 --- a/packages/axle/src/use.ts +++ b/packages/axle/src/use.ts @@ -10,8 +10,14 @@ export interface RunOptions { cloneResetValue?: boolean | ((value: V) => V) } -export type Run = (options?: RunOptions) => Promise - +export type UseAxleExtra = { + uploadProgress: Ref + downloadProgress: Ref + loading: Ref + error: Ref + abort(): void + resetValue(options?: ResetValueOptions): void +} export interface UseAxleRefs { value: Ref loading: Ref @@ -20,6 +26,10 @@ export interface UseAxleRefs { downloadProgress: Ref } +export type Run = { + (options?: RunOptions): Promise +} & UseAxleExtra + export interface UseAxleOptions> { url: string | (() => string) method: RunnerMethod @@ -40,18 +50,7 @@ export interface ResetValueOptions { cloneResetValue?: boolean | ((value: V) => V) } -export type UseAxleInstance = [ - value: Ref, - run: Run, - extra: { - uploadProgress: Ref - downloadProgress: Ref - loading: Ref - error: Ref - abort(): void - resetValue(options?: ResetValueOptions): void - } -] +export type UseAxleInstance = [value: Ref, run: Run, extra: UseAxleExtra] export interface CreateUseAxleOptions { axle: AxleInstance @@ -104,75 +103,79 @@ export function createUseAxle(options: CreateUseAxleOptions) { uploadProgress, } - let controller = new AbortController() - - const resetValue = (options: ResetValueOptions = {}) => { - const cloneResetValue = options.cloneResetValue ?? initialCloneResetValue ?? false - const cloneFn = - cloneResetValue === true - ? (v: V) => (v == null ? null : JSON.parse(JSON.stringify(v))) - : isFunction(initialCloneResetValue) - ? initialCloneResetValue - : (v: V) => v - value.value = cloneFn(initialValue as V) + const extra: UseAxleExtra = { + uploadProgress, + downloadProgress, + loading, + error, + abort, + resetValue, } - const run: Run = async (options: RunOptions = {}) => { - if (controller.signal.aborted) { - controller = new AbortController() - } + let controller = new AbortController() - const resetValueOption = options.resetValue ?? initialResetValue ?? false - if (resetValueOption === true) { - resetValue(options) - } + const run: Run = Object.assign( + async (options: RunOptions = {}) => { + if (controller.signal.aborted) { + controller = new AbortController() + } - uploadProgress.value = 0 - downloadProgress.value = 0 + const resetValueOption = options.resetValue ?? initialResetValue ?? false + if (resetValueOption === true) { + resetValue(options) + } - const url = options.url ?? normalizeValueGetter(initialUrlOrGetter) - const params = options.params ?? normalizeValueGetter(initialParamsOrGetter) - const config = options.config ?? normalizeValueGetter(initialConfigOrGetter) + uploadProgress.value = 0 + downloadProgress.value = 0 - onBefore(refs) + const url = options.url ?? normalizeValueGetter(initialUrlOrGetter) + const params = options.params ?? normalizeValueGetter(initialParamsOrGetter) + const config = options.config ?? normalizeValueGetter(initialConfigOrGetter) - loading.value = true + onBefore(refs) - try { - const response = await axle[method](url, params, { - signal: controller.signal, + loading.value = true - onUploadProgress(event) { - uploadProgress.value = event.progress ?? 0 - }, + try { + const response = await axle[method](url, params, { + signal: controller.signal, - onDownloadProgress(event) { - downloadProgress.value = event.progress ?? 0 - }, + onUploadProgress(event) { + uploadProgress.value = event.progress ?? 0 + }, - ...config, - }) + onDownloadProgress(event) { + downloadProgress.value = event.progress ?? 0 + }, - value.value = await onTransform(response as R, refs) - error.value = undefined - onSuccess(response as R, refs) - loading.value = false - onAfter(refs) + ...config, + }) - return response as R - } catch (responseError: any) { - error.value = responseError as Error - onError(responseError as Error, refs) - loading.value = false - onAfter(refs) + value.value = await onTransform(response as R, refs) + error.value = undefined + onSuccess(response as R, refs) + loading.value = false + onAfter(refs) - throw responseError - } - } + return response as R + } catch (responseError: any) { + error.value = responseError as Error + onError(responseError as Error, refs) + loading.value = false + onAfter(refs) - const abort = () => { - controller.abort() - } + throw responseError + } + }, + { + uploadProgress, + downloadProgress, + loading, + error, + abort, + resetValue, + } + ) if (immediate) { run({ @@ -182,18 +185,22 @@ export function createUseAxle(options: CreateUseAxleOptions) { }) } - return [ - value, - run, - { - loading, - error, - uploadProgress, - downloadProgress, - abort, - resetValue, - }, - ] + function resetValue(options: ResetValueOptions = {}) { + const cloneResetValue = options.cloneResetValue ?? initialCloneResetValue ?? false + const cloneFn = + cloneResetValue === true + ? (v: V) => (v == null ? null : JSON.parse(JSON.stringify(v))) + : isFunction(initialCloneResetValue) + ? initialCloneResetValue + : (v: V) => v + value.value = cloneFn(initialValue as V) + } + + function abort() { + controller.abort() + } + + return [value, run, extra] } return useAxle diff --git a/packages/playground/src/App.vue b/packages/playground/src/App.vue index c65a357..d15cea0 100644 --- a/packages/playground/src/App.vue +++ b/packages/playground/src/App.vue @@ -8,11 +8,11 @@ const model = ref({ name: '', }) -const [users, getUsers, { loading: isUsersLoading }] = apiGetUsers.use() +const [users, getUsers] = apiGetUsers.use() -const [mockUsers, getMockUsers, { loading: isMockUsersLoading }] = apiGetMockUsers.use() +const [mockUsers, getMockUsers] = apiGetMockUsers.use() -const [user, getUser, { loading: isUserLoading }] = apiGetUser.use({ +const [user, getUser] = apiGetUser.use({ pathParams: () => ({ id: id.value }), }) @@ -36,21 +36,21 @@ async function handleDelete() {
name: getUsers - loading: {{ isUsersLoading }} + loading: {{ getUsers.loading }} data: {{ users ?? 'No Data' }} Load name: getMockUsers - loading: {{ isMockUsersLoading }} + loading: {{ getMockUsers.loading }} data: {{ mockUsers ?? 'No Data' }} Load name: getUser - loading: {{ isUserLoading }} + loading: {{ getUser.loading }} data: {{ user ?? 'No Data' }}