import { useStorage } from '@vueuse/core' // 引入抽离的类型 import type { StorageOptions, StorageTool } from '@/type/storage' /** * 通用存储工具 * @param options 存储选项 * @returns 包含增删改查方法的对象 */ export function createStorage(options: StorageOptions = {}): StorageTool { const { type = 'localStorage', namespace = 'foreign_' } = options // 获取存储实例 const storageInstance = type === 'localStorage' ? localStorage : sessionStorage /** * 拼接键名,添加命名空间 */ const getKey = (key: string): string => { if (!key) { throw new Error('存储键名不能为空') } return namespace ? `${namespace}${key}` : key } const serializer = { read: (v: any) => v ? JSON.parse(v) : null, write: (v: any) => JSON.stringify(v), } return { /** * 获取存储值(响应式) * @param key 键名 * @param defaultValue 默认值 * @returns 响应式存储值 */ get: (key: string, defaultValue?: T) => { return useStorage(getKey(key), defaultValue ?? null, storageInstance, { serializer }) }, /** * 设置存储值 * @param key 键名 * @param value 值 */ set: (key: string, value: T) => { const storage = useStorage(getKey(key), null, storageInstance, { serializer }) storage.value = value }, /** * 移除存储值 * @param key 键名 */ remove: (key: string) => { storageInstance.removeItem(getKey(key)) }, /** * 清空存储 * @param withNamespace 是否只清空当前命名空间下的存储 */ clear: (withNamespace = true) => { if (withNamespace && namespace) { // 只清空当前命名空间的存储 Object.keys(storageInstance).forEach(key => { if (key.startsWith(namespace)) { storageInstance.removeItem(key) } }) } else { // 清空所有存储 storageInstance.clear() } }, /** * 检查键是否存在 * @param key 键名 * @returns 是否存在 */ has: (key: string) => { return Object.prototype.hasOwnProperty.call(storageInstance, getKey(key)) }, /** * 获取所有键 * @param withNamespace 是否只获取当前命名空间下的键 * @returns 键名数组 */ keys: (withNamespace = true) => { const keys = Object.keys(storageInstance) if (withNamespace && namespace) { return keys .filter(key => key.startsWith(namespace)) .map(key => key.replace(namespace, '')) } return keys } } } /** * 默认 localStorage 存储实例 */ export const useLocalStorage = createStorage({ type: 'localStorage' }) /** * 默认 sessionStorage 存储实例 */ export const useSessionStorage = createStorage({ type: 'sessionStorage' })