-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
index.ts
67 lines (58 loc) · 1.23 KB
/
index.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import type { MaybeComputedRef } from '@vueuse/shared'
import type { ComputedRef, WatchOptions } from 'vue-demi'
import { isRef, ref, unref, watch } from 'vue-demi'
export interface UseClonedOptions<T = any> extends WatchOptions {
/**
* Custom clone function.
*
* By default, it use `JSON.parse(JSON.stringify(value))` to clone.
*/
clone?: (source: T) => T
/**
* Manually sync the ref
*
* @default false
*/
manual?: boolean
}
export interface UseClonedReturn<T> {
/**
* Cloned ref
*/
cloned: ComputedRef<T>
/**
* Sync cloned data with source manually
*/
sync: () => void
}
export type CloneFn<F, T = F> = (x: F) => T
export function cloneFnJSON<T>(source: T): T {
return JSON.parse(JSON.stringify(source))
}
export function useCloned<T>(
source: MaybeComputedRef<T>,
options: UseClonedOptions = {},
) {
const cloned = ref<T>({} as T)
const {
manual,
clone = cloneFnJSON,
// watch options
deep = true,
immediate = true,
} = options
function sync() {
cloned.value = clone(unref(source))
}
if (!manual && isRef(source)) {
watch(source, sync, {
...options,
deep,
immediate,
})
}
else {
sync()
}
return { cloned, sync }
}