localStorage管理方案

565 阅读3分钟

1、前言


众所周知,cookie,localStorage,sessionStorage是前端领域关系很铁的三兄弟,每一位都有自己擅长的方面,都有着自己独特的地方,作为程序员的我们,只有做到物尽其用,才能写出高质量代码。

2、使用场景


  • cookie

cookie本身可以被访问请求所携带至,所以更多的场景是被用来做登录态使用,在这种场景下,由后端同学来为访问请求域名种上cookie,一般设置httpOnly为true,也就是不允许js等修改cookie,那自然前端也就没有太多的使用诉求。

  • sessionStorage

session本身的生命周期为窗口打开至关闭,不会在浏览器上长期存储,所以更多场景被使用做前端页面状态的缓存,因为h5页面本身是没有状态存储的,刷新即页面所有的一切回到最淳朴的状态,有一种场景,例如页面有填写姓名城市等表单元素,用户如果不小心碰到了刷新按钮,那自然是心态炸裂,那么为了防止炸裂的产生,我们可以使用session来存储用户填写的一些信息及状态,这样用户即使误触了刷新按钮也无妨,好感体验蹭蹭的往上涨。

  • localStorage

相对于sessionStorage来说,localStorage老大哥的生命周期那叫一个长寿,即没有人杀我我就永远存在,这样一来确实好处不少,但却有一个致命的问题,那就是无休止的存储,无限制的使用可能会造成存储爆表而造成一些不可预期的错误,那么今天我们就以它为主角,来展开一下关于localStorage的管理方案

3、正题,localStorage管理


  • 以往的使用方式
localStorage.setItem(key, value); // 存
localStorage.getItem(key); // 取
localStorage.removeItem(); // 删

这样的方式存储下来,一是存储爆表问题,二是这样的方式显得很杂乱,类似于js中的全局变量,杂乱无章,很容易冲突 image.png

  • 今天实现的使用方式
storage.set(key, value, expired); // 存,但需设置过期时间
storage.get(key); // 取
storage.remove(key); // 删
storage.clearExpired(); // 删除过期存储,该方法推荐放置于公用页面加载处调用,即每次页面加载清除掉过期的存储

就,很舒服,设置过期时间防止爆表问题,以项目维度存储至一个字段下避免项目之间冲突,当然也可以根据自己需要调整存储维度 image.png

4、话不多说,上代码

/**
 * @description localStorage统一管理
 * @list
 *      storage.set(key, value, expired)    - 设置 storage
 *      storage.get(key)                    - 获取 storage
 *      storage.remove(key)                 - 删除 storage
 *      storage.clearExpired()              - 清除已过期的 storage
 * @whyDo
 *      用户 localStorage 本地存储大小是有限的,如果不限制使用,没有合理管理,将造成不可预期的问题
 * @whatDo
 *      统一管理项目 localStorage 使用,增加过期时间,页面加载时自动清除过期的存储
 */

const localStorageKey = "project_storage_info";

class Storage {
    constructor() {
        this.cache = {};
    }
    set(key, value, expiredTime = 1) {
        // expiredTime 单位为天
        this.cache = this.get();
        if (this.cache[key]) delete this.cache[key];
        const info = {
            value,
            expired: +new Date() + expiredTime*24*60*60*1000
        };
        this.cache[key] = info;
        localStorage.setItem(localStorageKey, JSON.stringify(this.cache));
    }
    get(key) {
        const str = localStorage.getItem(localStorageKey);
        this.cache = str ? JSON.parse(str) : {};
        if (key) {
            if (this.cache[key]) return this.cache[key].value;
            return "";
        }
        return this.cache;
    }
    remove(key) {
        // 此处可根据实际情况提供全部删除方法,个人感觉有一定风险
        if (!key) throw new Error("localStorage 删除操作必须传入对应的 key 值!!!");
        this.cache = this.get();
        delete this.cache[key];
        localStorage.setItem(localStorageKey, JSON.stringify(this.cache));
    }
    clearExpired() {
        this.cache = this.get();
        if (!Object.keys(this.cache).length) return;
        for(const key in this.cache) {
            if (this.cache[key].expired < +new Date()) {
                delete this.cache[key];
            }
        }
        localStorage.setItem(localStorageKey, JSON.stringify(this.cache));
    }
}

export default new Storage();

5、完结

遇事多思考,编码需谨慎;
致敬每一个前端coder;Respect;

666.jpeg