import { PluginObject } from 'vue' type typeFn = 'sessionStorage' | 'localStorage' interface IStorageData { key: string, value: T, expire: number, } function setItem (fn: typeFn, key: string, value: T, expire: number = -1) : T { window[fn].setItem(key, JSON.stringify({ key, value, expire })) return value } function getItem (fn: typeFn, key: string, defValue: T | null = null) : T | null { let data = window[fn].getItem(key) if (data === null) { return defValue } const { expire, value } = JSON.parse(data) as IStorageData if (expire === -1 || Date.now() < expire) { return value } removeItem(fn, key) return defValue } function removeItem(fn: typeFn, key: string): void { window[fn].removeItem(key) } function updateItem (fn: typeFn, key: string, value: T, expire?: number) : T { const data = window[fn].getItem(key) if (data) { const { value: prevValue, expire: prevExpire } = JSON.parse(data) as IStorageData if (prevExpire === -1 || Date.now() < prevExpire) { if (Array.isArray(value)) { value = [...prevValue as any as [], ...value] as any as T } else { value = Object.assign({}, prevValue, value) } if (!expire) { expire = prevExpire } } } return setItem(fn, key, value, expire) } function clear(fn: typeFn) : void { window[fn].clear() } function generate (fn: typeFn) { return { setItem (key: string, value: T, expire = -1) : T { return setItem(fn, key, value, expire) }, getItem (key: string, defValue = null) : T | null{ return getItem(fn, key, defValue) }, removeItem (key) { return removeItem(fn, key) }, updateItem (key: string, value: T, expire?) { return updateItem(fn, key, value, expire) }, clear () { return clear(fn) }, generate (key: string) { return { setItem (value: T, expire = -1) : T { return setItem(fn, key, value, expire) }, getItem (defValue = null) : T | null{ return getItem(fn, key, defValue) }, removeItem () { return removeItem(fn, key) }, updateItem (value: T, expire?) { return updateItem(fn, key, value, expire) }, clear () { return clear(fn) }, } } } } export const cache = generate('sessionStorage') export const local = generate('localStorage') const Storage: PluginObject = { install(Vue) { Vue.prototype.$cache = cache Vue.prototype.$local = local } } export default Storage