Newer
Older
import { cloneDeep, isEqual } from 'lodash'
import { computed, ComputedGetter, ComputedRef, readonly, Ref, ref, watch, watchEffect } from 'vue'
import { formatISO, parseISO } from 'date-fns'
export function computedIter<T>(fn: ComputedGetter<Iterable<T>>): ComputedRef<T[]> {
return computed(() => Array.from(fn()))
}
export const useId = (() => {
let _id = 0
return function useId(prefix = 'component') {
return readonly(ref(`${prefix}-${_id++}`))
}
})()
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
export function useAsyncFunction<F extends (...args: never[]) => ReturnType<F>>(
fn: F,
): { isLoading: Ref<boolean>; fn: (...args: Parameters<F>) => ReturnType<F> } {
const isLoading = ref(false)
function wrapper(...args: Parameters<F>): ReturnType<F> {
isLoading.value = true
try {
return fn(...args)
} finally {
isLoading.value = false
}
}
return { fn: wrapper, isLoading }
}
export function useUpdatableState<T>(
externalStateRef: Ref<T>,
onUpdate: (value: T) => void,
clone: (value: T) => T = cloneDeep,
): Ref<T> {
const localRef = ref()
watchEffect(() => {
localRef.value = clone(externalStateRef.value)
})
watch(
localRef,
(newValue) => {
if (!isEqual(newValue, externalStateRef.value)) {
onUpdate(newValue)
}
},
{ deep: true },
)
return localRef
}
export function useFormattedISODate(date: Ref<Date>) {
return computed({
get() {
return formatISO(date.value, { representation: 'date' })
},
set(dateValue: string) {
date.value = parseISO(dateValue)
},
})
}