41 lines
983 B
TypeScript
41 lines
983 B
TypeScript
import { ref, watch, type Ref } from 'vue'
|
|
|
|
/**
|
|
* JSON persisted ref for client-only state (replaces @vueuse/useStorage for shallow objects).
|
|
*/
|
|
export function useLocalStorageRef<T extends object>(key: string, defaults: () => T): Ref<T> {
|
|
const data = ref(defaults()) as Ref<T>
|
|
if (import.meta.server) return data
|
|
|
|
try {
|
|
const raw = localStorage.getItem(key)
|
|
if (raw) {
|
|
const parsed = JSON.parse(raw)
|
|
const def = defaults()
|
|
if (Array.isArray(def) && Array.isArray(parsed)) {
|
|
data.value = parsed as T
|
|
} else if (def !== null && typeof def === 'object' && !Array.isArray(def)) {
|
|
data.value = { ...(def as object), ...(parsed as object) } as T
|
|
} else {
|
|
data.value = parsed as T
|
|
}
|
|
}
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
|
|
watch(
|
|
data,
|
|
(v) => {
|
|
try {
|
|
localStorage.setItem(key, JSON.stringify(v))
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
},
|
|
{ deep: true }
|
|
)
|
|
|
|
return data
|
|
}
|