-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
useLoadings.ts
52 lines (46 loc) · 1.48 KB
/
useLoadings.ts
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
import { useReactive, useComputed, readonly } from 'veact'
/**
* @example
* const loadings = useLoadings('fetchList', 'postForm');
* loadings.start('fetchList');
* loadings.end('fetchList');
* loadings.isLoading('fetchList');
* loadings.promise('fetchList', axios.get({ ... }));
*/
export function useLoadings(...names: Array<string>) {
const loadingMap = useReactive(new Map<string, boolean>(names.map((name) => [name, false])))
const loadingNames = useComputed(() => {
return Array.from(loadingMap.keys())
})
const isLoading = (name: string): boolean => Boolean(loadingMap.get(name))
const isFinished = (name: string): boolean => !isLoading(name)
const isSomeLoading = () => loadingNames.value.some((name) => isLoading(name))
const isAllFinished = () => loadingNames.value.every((name) => isFinished(name))
const setLoading = (key: string, value: boolean) => {
loadingMap.set(key, value)
}
const start = (name: string) => setLoading(name, true)
const stop = (name: string) => setLoading(name, false)
const add = (name: string): void => {
if (!loadingMap.has(name)) {
setLoading(name, false)
}
}
const handlePromise = <T>(name: string, promise: Promise<T>): Promise<T> => {
start(name)
promise.finally(() => stop(name))
return promise
}
return {
$map: readonly(loadingMap),
promise: handlePromise,
set: setLoading,
start,
stop,
add,
isLoading,
isFinished,
isSomeLoading,
isAllFinished,
}
}