前言
在前端开发中,localStorage的使用是非常多的,然而原生的localStorage有些功能是没有的,比如:
- 无法设置每一个键的过期时间
- 无法按模块管理localStorage
一、如何使用
先来看看如何使用的,再看实现方法:
1、初始化时传入moduleName
let storage = new Storage('user'); // 设置了模块名为user
storage.setItem('name', '张三', 60 * 60 * 24); // 过期时间1天
storage.setItem('age', 18);
storage.clear(); // 清空所有localStorage
storage.clear('user'); // 清空模块名user的localStorage
2、初始化时不传入moduleName
let storage = new Storage();
storage.setItem('name', '张三', 60 * 60 * 24, 'user'); // 过期时间1天、模块名为user
storage.setItem('name', 'mac', 'system'); // 模块名为system
storage.getItem('name', 'system'); // 获取模块system下的name
storage.clear('system'); // 清空模块名system的localStorage
获取时如果过期了,则会自动清空数据,并返回状态
二、实现代码
class Storage {
constructor(moduleName) {
this.moduleName = moduleName;
this.storage = localStorage || window.localStorage;
this.status = {
SUCCESS: 0,
FAILURE: 1, // 失败
OVERFLOW: 2, // 超出限制,localstorage最大支持5M的数据(每个浏览器各自又有些不同)
TIMEOUT: 3 // 过期
};
}
setItem(key, value) {
let expire, moduleName, args = Array.prototype.slice.call(arguments, 2);
if (args.length > 0) { // 处理参数顺序
if (typeof args[0] == 'number') {
[expire, moduleName] = args;
} else {
[moduleName, expire] = args;
}
}
key = this.normalizeKey(key, moduleName);
let status = this.status.SUCCESS, data = value;
if (!expire && ['[object Object]', '[object Array]'].indexOf(Object.prototype.toString.call(value)) > -1) { // 没有设置过期时间 + 是对象或数组
data = JSON.stringify(value);
} else if (expire) {
data = JSON.stringify({
value,
_expireTime_: new Date().getTime() + expire * 1000
});
}
try {
this.storage.setItem(key, data);
} catch(e) {
status = this.status.OVERFLOW;
}
return status;
}
getItem(key, moduleName) {
let status = this.status.SUCCESS, data = null;
key = this.normalizeKey(key, moduleName);
try {
data = this.storage.getItem(key);
} catch(e) {
status = this.status.FAILURE;
}
try {
data = JSON.parse(data);
} catch (error) {}
if (data && data.value && data._expireTime_) { // 设置了失效时间
if (new Date().getTime() > data._expireTime_) { // 失效
data = null;
status = this.status.TIMEOUT;
this.storage.removeItem(key)
} else {
data = data.value;
}
}
return {
status,
value: data
};
}
clear(moduleName) {
if (moduleName) {
const keys = Object.keys(this.storage);
keys.forEach(key => {
if (key.indexOf(moduleName + '/') === 0) {
this.storage.removeItem(key);
}
})
} else {
this.storage.clear();
}
}
normalizeKey(key, moduleName) {
let ModuleName = moduleName || this.moduleName; // 单独设置就用单独设置的,否则用初始化时候传入的
if (typeof key !== 'string') {
console.warn(`${key} used as a key, but it is not a string.`);
key = String(key);
}
return `${ModuleName ? ModuleName + '/' : ''}${key}`;
}
}
最后
以上就是我自己封装的localStorage啦,希望可以帮到有需要的人,如果可以的话,麻烦点个赞或者收藏下呦~