113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
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: <T = any>(key: string, defaultValue?: T) => {
|
|
return useStorage<T | null>(getKey(key), defaultValue ?? null, storageInstance, { serializer })
|
|
},
|
|
|
|
/**
|
|
* 设置存储值
|
|
* @param key 键名
|
|
* @param value 值
|
|
*/
|
|
set: <T = any>(key: string, value: T) => {
|
|
const storage = useStorage<T | null>(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' }) |