让localStorage更好用、类型更安全,soon-storage 2.0来了

576 阅读2分钟

localStorage是前端数据持久化的最常用选择,没有之一。
但直接使用localStorage会很麻烦,特别某个键值频繁使用的时候。

原生localStorage的缺陷

1. 空值处理的防御性编码负担

// 必须手动处理null情况
const userConfig = localStorage.getItem('config')
  ? JSON.parse(localStorage.getItem('config')!)
  : DEFAULT_CONFIG;

2. TypeScript类型安全缺失

// 强制类型断言存在运行时风险
const settings = JSON.parse(
  localStorage.getItem('appSettings')!
) as AppSettings; // 实际存储可能是非法格式

3. 序列化/反序列化成本

// Date对象需要手动转换,每次都需要
const lastActive = new Date(
  localStorage.getItem('lastActive')! 
);

soon-storage 2.0的核心优势

  • 可统一设置键前缀(如微前端时可避免键冲突)
  • 支持localStorage和sessionStorage
  • 创建实例时,定义数据转换getter、setter,而非使用时每次转换。
  • 根据创建时的getter、setter自动获取TS类型。
  • 可以设置默认值,默认值可以具体值,也可是一个函数返回默认值。
  • onSet设置完成、 onRemoved移除完成事件监听。
  • 可以批量获取、设置、移除该实例下的键值。

代码示例

import { createStorage, parsers as p } from "soon-storage";

const storage = createStorage({
  // key前缀
  prefix: "soon-",
  // 可选用 localStorage 或 SessionStorage
  provider: () => localStorage,
  // 内置的转换string,number,boolean,json 
  // 可自定义转换如下方的Date类型
  transforms: {
    name: p.string("Guest"), // name包含默认值Guests
    age: p.number(() => Math.random() * 100), // age包含一个返回随机数的默认值
    birth: p.define({
      getter: (val) => (val === null ? null : new Date(val)),
      setter: (val) => val.toISOString(),
    }),//birth 自定义的Date格式转化
    graduated: p.boolean(), // graduated 无默认值,空值时返回null
    school: p.json<{
      name: string;
      address: string;
    }>(), // school 无默认值的json数据
  },

  onSet: (key, value) => {
    console.log(`set ${key} to ${value}`);
    // 当key被设置完成时的事件
  },
  onRemoved: (key) => {
    console.log(`removed ${key}`);
    //当key被移除时的事件
  },

});

// 设置一个值
storage.birth.set(new Date("2008-08-08"));
// 获取一个值
storage.birth.get();
// 移除一个值
storage.birth.remove();

// 获取值
console.log(storage.name.get()); // 未设置时,会返回 "Guest" 
console.log(storage.age.get()); // 未设置时,会返回随机数字 (0,100)
console.log(storage.graduated.get()); // 未设置时,会返回 null
console.log(storage.school.get()); // 未设置时,会返回 null

// 设置所有值
storage.$.setAll({
  name: "Lucy",
  age: 100,
  birth: new Date(),
  graduated: false,
  school: {
    name: "Green Land",
    address: "Qingdao",
  },
});

// 获取所有值
const allData = storage.$.getAll();
console.log(allData);

// 移除所有值
// 仅会移除当前实例下的值
storage.$.removeAll();

热情地欢迎各位兄弟姐妹的大力支持!
github: github.com/leafio?tab=…
期待至少一个项目能达成1000个star
期待至少一个npm能达成每周1000次下载