SimpleDB 是一个轻量级 IndexedDB 封装库,基于 Promise、自动事务管理、声明式 schema 和统一错误处理,提供 add/get/put/delete/where 等链式 API,聚焦高频操作且默认主键为 id。

IndexedDB 是浏览器端强大的结构化存储方案,但原生 API 冗长、异步嵌套深、错误处理繁琐。直接封装一个轻量通用的类库(类似 Dexie.js 的简化版)能显著提升开发效率和可维护性。
核心设计目标:简洁、Promise 化、支持事务自动管理
不追求功能全覆盖,聚焦高频场景:打开数据库、增删改查、批量操作、索引查询。所有方法返回 Promise,拒绝时统一抛出带上下文的错误(如 DBError: failed to add record to 'users')。
- 数据库初始化与版本升级通过声明式 schema 定义(对象结构 + keyPath + indexes)
- 每个操作自动选择合适事务模式(
readonly或readwrite),无需手动传参 - 主键默认为
id(可配置),自动生成 UUID 或递增数字(按需启用)
基础类骨架:DB 类封装关键生命周期
用 ES6 class 封装,内部缓存 IDBDatabase 实例,避免重复打开。构造时接收名称、版本、schema 配置:
class SimpleDB {
constructor(name, version, schema) {
this.name = name;
this.version = version;
this.schema = schema;
this.db = null;
}
async open() {
return new Promise((resolve, reject) => {
const req = indexedDB.open(this.name, this.version);
req.onerror = () => reject(new Error(`Open failed: ${req.error?.message}`));
req.onupgradeneeded = (e) => this.#upgrade(e.target.result);
req.onsuccess = () => {
this.db = req.result;
resolve(this.db);
};
});
}
#upgrade(db) {
Object.entries(this.schema).forEach(([storeName, config]) => {
if (!db.objectStoreNames.contains(storeName)) {
const store = db.createObjectStore(storeName, { keyPath: config.keyPath || 'id' });
(config.indexes || []).forEach(([name, key, opts]) => store.createIndex(name, key, opts));
}
});
}
}
数据操作方法:链式调用风格,隐藏事务细节
提供 add()、get()、put()、delete()、toArray()、where() 等方法。所有方法内部自动创建事务并返回 Promise:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
-
add(storeName, item)→ 自动使用readwrite事务,返回插入后的 key -
get(storeName, key)→readonly事务,返回匹配记录或 undefined -
where(storeName).equals(key).toArray()→ 支持简单索引查询(如email字段) -
bulkAdd(storeName, items)→ 批量写入,失败时整个事务回滚
例如:await db.add('users', { name: 'Alice', email: 'a@b.com' });await db.where('users').index('email').equals('a@b.com').first()。
错误处理与调试友好性
所有异常统一包装为 DBError 类,附带 store 名称、操作类型、原始错误信息。开发时可开启日志开关,输出事务执行时间、SQL 类似语句(如 [GET] users where id = 123)。
不复杂但容易忽略:在页面卸载前调用 db.close() 防止连接泄漏;对大对象(如 Blob、File)存取需注意 IndexedDB 的序列化限制——建议转为 ArrayBuffer 或 URL.createObjectURL 后存字符串。


















