import { shallowRef, ref, watchEffect, unref } from "vue";
import type { Ref } from "vue";
interface UseAsyncOptions<T, Params extends any[]> {
immediate?: boolean;
shallow?: boolean;
params?: Params;
onError?: (err: unknown) => void;
onSuccess?: (data: T) => void;
onBefore?: () => void;
}
interface UseAsyncReturn<T, Params extends any[]> {
data: Ref<T | undefined>;
loading: Ref<boolean>;
error: Ref<unknown>;
execute: (...args: Params) => Promise<T | undefined>;
}
export function useAsync<T, Params extends any[] = []>(
fn: (...args: Params) => Promise<T>,
options: UseAsyncOptions<T, Params> = {}
): UseAsyncReturn<T, Params> {
const {
immediate = true,
shallow = false,
params = [] as unknown as Params,
onError,
onSuccess,
onBefore,
} = options;
const data = shallow ? shallowRef<T>() : ref<T>();
const loading = ref(false);
const error = ref<unknown>();
const execute = async (...args: any) => {
try {
loading.value = true;
error.value = null;
onBefore && onBefore();
const response = await fn(...args);
data.value = response;
onSuccess && onSuccess(response);
return response;
} catch (err) {
error.value = err;
onError && onError(err);
return undefined;
} finally {
loading.value = false;
}
};
if (immediate) {
watchEffect(() => {
if (params) {
execute(params);
}
});
}
return {
data,
loading,
error,
execute,
};
}
使用
import { useAsync } from "@/composables/useAsync";
const option = ref({})
// const state = ref<Sales[]>([]);
// const getData = () => {
// getSalesList().then(res => {
// if (res.code === 200) {
// state.value = res.data!;
// setOption();
// }
// })
// }
// onMounted(() => {
// getData();
// })
const { data:state, loading } = useAsync(getSalesList, {
onSuccess: (res) => {
console.log('销售数据加载成功',res);
// state.value = res.data!;
if (res.code === 200) {
setOption(res.data!);
}
},
onError: (err) => {
console.error('销售数据加载失败',err);
}
})