html IndexedDB数据库使用

2026-04-24 13:00:09 1059阅读 0评论

用IndexedDB做本地数据持久化:小而稳的前端数据仓库

在移动端与浏览器端,频繁的网络请求和数据往返让人头大,尤其在弱网或离线场景下,想让数据“先放着、后补上”却不容易。IndexedDB 作为一种轻量级的客户端存储方案,能让你在不依赖同步请求的前提下,稳定地持久化结构化数据,保存搜索记录、任务清单、离线文章等场景都适配。

为什么用IndexedDB而不是localStorage

localStorage 是常见选择,但它更适合存储简单的键值对或小量字符串数据,结构化数据、事务、索引与查询能力不如 IndexedDB。当需要频繁增删改查、按条件筛选或在离线与在线间平滑切换时,IndexedDB 的事务型写法与索引组织能显著降低数据操作的不确定性与耦合度。

实战:搭建你的本地数据仓库

1. 创建数据库与对象存储

const dbName = 'localData';
const dbVersion = 1;

let db;

// 打开数据库
const openDB = () => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(dbName, dbVersion);
    request.onupgradeneeded = (e) => {
      const db = e.target.result;
      if (!db.objectStoreNames.contains('items')) {
        const store = db.createObjectStore('items', {
          keyPath: 'id',
          autoIncrement: true,
        });
        store.createIndex('nameIndex', 'name', { unique: false });
        store.createIndex('createdIndex', 'created', { unique: false });
      }
      resolve(db);
    };

    request.onsuccess = (e) => {
      db = e.target.result;
      resolve(db);
    };

    request.onerror = (e) => {
      reject(e);
    };
  });
};

// 使用前先打开数据库
openDB().then(() => {
  // 后续操作数据库
}).catch((error) => {
  console.error('数据库打开失败:', error);
});

2. 写入数据

const addItem = (item) => {
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['items'], 'readwrite');
    const store = transaction.objectStore('items');
    const request = store.add(item);
    request.onsuccess = () => resolve(request.result);
    request.onerror = (e) => reject(e);
  });
};

3. 查询与索引

const getItemsByName = (name) => {
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['items'], 'readonly');
    const store = transaction.objectStore('items');
    const index = store.index('nameIndex');
    const request = index.getAll(`^${name}`); // 模糊匹配示例
    request.onsuccess = (e) => resolve(e.target.result);
    request.onerror = (e) => reject(e);
  });
};

4. 更新与删除

const updateItem = (id, updateData) => {
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['items'], 'readwrite');
    const store = transaction.objectStore('items');
    const request = store.put({ ...updateData, id });
    request.onsuccess = () => resolve();
    request.onerror = (e) => reject(e);
  });
};

const deleteItem = (id) => {
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['items'], 'readwrite');
    const store = transaction.objectStore('items');
    const request = store.delete(id);
    request.onsuccess = () => resolve();
    request.onerror = (e) => reject(e);
  });
};

使用场景与注意事项

  • 离线优先:在 PWA、移动端网页中,先写入本地再与服务器异步同步,避免网络抖动导致的数据丢失。
  • 数据版本化与备份:在 onupgradeneeded 中升级索引与结构,并定期导出或同步备份。
  • 性能与内存:避免在主线程中执行长时间的读写,使用事务与请求回调控制操作节奏。
  • 数据清理:设置过期策略或自动清理策略,防止本地存储膨胀。

结语

IndexedDB 并不复杂,关键在用对场景与数据模型。它让客户端在没有稳定网络时也能高效地管理结构化数据,是构建离线优先应用的实用工具。把数据持久化与查询路径想清楚,再结合业务逻辑落地到具体操作,就能在页面与数据之间建立起稳健的桥梁。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
验证码
评论列表 (暂无评论,1059人围观)

还没有评论,来说两句吧...

目录[+]