-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathuseRequest.ts
More file actions
54 lines (50 loc) · 1.7 KB
/
useRequest.ts
File metadata and controls
54 lines (50 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { ElLoadingService } from "element-plus"
import { Ref, WatchSource, onMounted, ref, watch } from "vue"
type Option<T, P> = {
manual?: boolean
defaultValue?: T
loadingTarget?: string | Ref<HTMLElement>
loadingText?: string
defaultParam?: P
deps?: WatchSource<unknown> | WatchSource<unknown>[]
onSuccess?: (result: T) => void,
onError?: (e: unknown) => void
}
type Result<T, P> = {
data: Ref<T>
refresh: (p?: P) => void
refreshAsync: (p?: P) => Promise<void>
loading: Ref<boolean>
}
export const useRequest = <P, T>(getter: (p?: P) => Promise<T> | T, option?: Option<T, P>): Result<T, P> => {
const {
manual = false,
defaultValue, defaultParam,
loadingTarget, loadingText,
deps,
onSuccess, onError,
} = option || {}
const data: Ref<T> = ref(defaultValue) as Ref<T>
const loading = ref(false)
const refreshAsync = async (p?: P) => {
loading.value = true
const loadingEl = typeof loadingTarget === "string" ? loadingTarget : loadingTarget?.value
const loadingInstance = loadingEl ? ElLoadingService({ target: loadingEl, text: loadingText }) : null
try {
const value = await getter?.(p)
data.value = value
onSuccess?.(value)
} catch (e) {
onError?.(e)
} finally {
loading.value = false
loadingInstance?.close?.()
}
}
const refresh = (p?: P) => { refreshAsync(p) }
if (!manual) onMounted(() => refresh(defaultParam))
if (deps && (!Array.isArray(deps) || deps?.length)) {
watch(deps, () => refresh(defaultParam))
}
return { data, refresh, refreshAsync, loading }
}