useAsyncState
响应式异步状态。不会阻塞你的 setup 函数,并且会在 Promise 准备就绪后触发更改。state 默认为 shallowRef。
Demo
<script setup lang="ts">
import { reactify, useAsyncState } from '@vueuse/core'
import axios from 'axios'
import YAML from 'yaml'
const stringify = reactify(
(input: any) => YAML.stringify(input, (k, v) => {
if (typeof v === 'function') {
return undefined
}
return v
}, {
singleQuote: true,
flowCollectionPadding: false,
}),
)
const { isLoading, state, isReady, execute } = useAsyncState(
(args) => {
const id = args?.id || 1
return axios.get(`https://jsonplaceholder.typicode.com/todos/${id}`).then(t => t.data)
},
{},
{
delay: 2000,
resetOnExecute: false,
},
)
</script>
<template>
<div>
<note>Ready: {{ isReady.toString() }}</note>
<note>Loading: {{ isLoading.toString() }}</note>
<pre lang="json" class="ml-2">{{ stringify(state) }}</pre>
<button @click="() => execute(2000, { id: 2 })">
Execute
</button>
</div>
</template>
使用
import { useAsyncState } from '@vueuse/core'
import axios from 'axios'
const { state, isReady, isLoading } = useAsyncState(
axios
.get('https://jsonplaceholder.typicode.com/todos/1')
.then(t => t.data),
{ id: null },
)
手动触发异步函数
你也可以 手动触发 它。当你想要控制异步函数何时执行时,这会很有用。
<script setup lang="ts">
import { useAsyncState } from '@vueuse/core'
// useAsyncState:用于包装一个异步函数(action),并返回响应式状态。
// 初始状态值,组件加载时 state 的值为 ''
// { immediate: false }:表示不会在组件初始化时立即执行异步函数
// 返回的 state 是响应式的,可直接绑定到模板中
// 提供 isLoading、isReady、error 等状态,便于 UI 控制
const { state, execute, executeImmediate } = useAsyncState(action, '', { immediate: false })
// 一个异步函数,接受任意参数并返回 Promise。
async function action(event) {
await new Promise(resolve => setTimeout(resolve, 500))
return `${event.target.textContent} clicked!`
}
</script>
<template>
<p>State: {{ state }}</p>
<button class="button" @click="executeImmediate">
Execute now
</button>
<button class="ml-2 button" @click="event => execute(500, event.target)">
Execute with delay
</button>
</template>
适用场景:
- 按钮点击后请求数据:如提交表单、刷新数据、加载更多内容。
- 用户输入后请求 API:如搜索框输入后请求搜索结果。
- 延迟加载组件状态:避免组件初始化时不必要的请求。
- 手动刷新机制:提供 “重试” 或 “刷新” 按钮功能。
类型声明
export interface UseAsyncStateReturnBase<
Data,
Params extends any[],
Shallow extends boolean,
> {
state: Shallow extends true ? Ref<Data> : Ref<UnwrapRef<Data>> // 响应式结果值(初始为 initialState,异步完成后更新)
isReady: Ref<boolean> // 是否已完成
isLoading: Ref<boolean> // 是否正在加载中
error: Ref<unknown> // 异步执行出错时的错误对象
execute: (delay?: number, ...args: Params) => Promise<Data> // 手动执行异步函数(支持延迟)
executeImmediate: (...args: Params) => Promise<Data> // 不延迟立即执行
}
export type UseAsyncStateReturn<
Data,
Params extends any[],
Shallow extends boolean,
> = UseAsyncStateReturnBase<Data, Params, Shallow> &
PromiseLike<UseAsyncStateReturnBase<Data, Params, Shallow>>
export interface UseAsyncStateOptions<Shallow extends boolean, D = any> {
/**
* 当 "immediate" 为 true 时,promise 第一次执行的延迟时间(以毫秒为单位)。
*
* @default 0
*/
delay?: number
/**
* 在函数调用后立即执行 promise。
* 如果设置了延迟,将会应用该延迟。
* 当设置为 false 时,你需要手动执行它。
*
* @default true
*/
immediate?: boolean
/**
* 捕获错误时的回调函数。
*/
onError?: (e: unknown) => void
/**
* 成功回调
* @param {D} data
*/
onSuccess?: (data: D) => void
/**
* 是否在执行 promise 之前将 state 设置为 initialState。
* 这在多次调用 execute 函数时(例如,用于刷新数据)会很有用。设置为 false 时,当前 state 保持不变,直到 promise 被解析。
*
* @default true
*/
resetOnExecute?: boolean
/**
* 是否使用 shallowRef.
*
* @default true
*/
shallow?: Shallow
/**
*
* 是否在执行失败时抛出异常
*
* @default false
*/
throwError?: boolean
}
/**
* 响应式的异步状态。不会阻塞你的 setup 函数,并且在 promise 准备好后会触发变更。
*
* @see https://vueuse.org/useAsyncState
* @param promise The promise / async function to be resolved
* @param initialState The initial state, used until the first evaluation finishes
* @param options
*/
export declare function useAsyncState<
Data,
Params extends any[] = any[],
Shallow extends boolean = true,
>(
promise: Promise<Data> | ((...args: Params) => Promise<Data>),
initialState: Data,
options?: UseAsyncStateOptions<Shallow, Data>,
): UseAsyncStateReturn<Data, Params, Shallow>