在前端开发中,数据存储和管理是必不可少的一部分。传统的数据存储方式包括 Cookie, localStorage 等,但随着业务的复杂性增加,这些方式已经无法满足我们的需求。IndexedDB 是 HTML5 中的新 API,针对大量结构化数据的存储和检索提供了非常强大的支持。同时,随着 PWA 的兴起,利用 IndexedDB 进行数据存储和管理也成为了 Web 应用中比较流行的做法。
本文将会介绍 PWA 中使用 IndexedDB 进行数据存储和管理的方法,以及如何应对 IndexedDB 在使用过程中的奇怪问题。
为什么选择 IndexedDB?
在了解 IndexedDB 之前,我们先来看一下传统的数据存储方式 localStorage。localStorage 是一种键值对存储方式,相对于 Cookie 而言,存储容量更大,且没有过期时间限制。但 localStorage 有一些明显的限制:
- 相比较于 indexedDB,localStorage 可以存储的数据量较小,一般只有几个 MB。而在 indexedDB 中,存储的数据量可以达到上百 MB。
- localStorage 只能存储字符串类型的数据,而 indexedDB 可以存储任何类型的数据。
相比较而言,IndexedDB 提供了更大的存储空间和更丰富的存储类型。而且,IndexedDB 通过异步 API 提供了更好的性能。在实际的业务场景中,我们通常需要存储一些精细的结构化数据,针对这种场景,IndexedDB 是一个很好的选择。
IndexedDB 的基本概念
IndexedDB 存储的数据由若干个对象仓库(object store)组成,每个对象仓库存储了相似的数据类型。你可以把一个对象仓库想象为一个表格。每个对象仓库都可以定义一个或多个索引(Index),以便在查找数据时提高效率。
在进行 IndexedDB 操作之前,需要通过以下步骤建立数据库连接:
-- -------------------- ---- ------- ----- ------- - ----------------------------------- -- ----- -- - ----- --- ----------------- ------- -- - ----------------- - -- -- ----------------------- --------------- - ------ ----------------------- - ----- -- - ----- -- - ------------------- ----------------------------- - -------- ---- -- ----------- - --
上述代码用于打开一个名为 myDatabase
,版本为 1
的 IndexedDB。如果该数据库已经存在,则打开该数据库,否则会创建一个新的数据库。在创建数据库时,我们需要指定每个对象仓库的结构,并指定其中的一个属性为主键(keyPath)。
对于已经存在的数据库,我们需要将数据库升级到最新版本。IndexedDB 会根据版本号决定是否执行升级操作。我们可以通过事件监听 onupgradeneeded
来执行升级操作。下面的代码演示了如何在升级数据库时新增一个名为 books
的对象仓库:
request.onupgradeneeded = event => { const db = event.target.result db.createObjectStore("books", { keyPath: "id" }) }
IndexedDB 常用操作
添加数据
使用 add
方法可以添加数据到指定的对象仓库中。在添加之前,需要通过 transaction
方法开启一个事务。事务是 IndexedDB 操作的基本单元,用于确保数据的完整性和一致性。下面的代码演示了如何向 books
对象仓库中添加一条数据:
const transaction = db.transaction(["books"], "readwrite") const store = transaction.objectStore("books") store.add({ id: 1, title: "Harry Potter", author: "J.K. Rowling" })
更新数据
使用 put
方法可以对指定的数据进行更新。使用 get
方法可以获取一条指定数据,然后对其进行修改,最后将修改后的数据写回到对象仓库中。下面的代码演示了如何更新一条数据:
const transaction = db.transaction(["books"], "readwrite") const store = transaction.objectStore("books") const request = store.get(1) request.onsuccess = () => { const book = request.result book.author = "J.K. Rowling & Jack Thorne" store.put(book) }
删除数据
使用 delete
方法可以删除一条指定数据。
const transaction = db.transaction(["books"], "readwrite") const store = transaction.objectStore("books") store.delete(1)
查询数据
使用 getAll
方法可以获取指定对象仓库中的所有数据。
const transaction = db.transaction(["books"]) const store = transaction.objectStore("books") const request = store.getAll() request.onsuccess = () => { console.log(request.result) }
索引查询
使用索引可以加快对数据的查询。我们可以通过 createIndex
方法为一个对象仓库添加一个或多个索引。
-- -------------------- ---- ------- ----- ----------- - ------------------------- ----- ----- - -------------------------------- -------------------------- -------- -- ------- ----- ------ -- ----- ----- - -------------------- ----- ------- - ------------------- -------- ----------------- - -- -- - --------------------------- -
IndexedDB 的注意事项
- IndexedDB API 操作都是异步的,这就意味着我们通常需要借助
async/await
或者 Promise 进行异步编程。 - IndexedDB 在浏览器直接存储数据,一旦存储错误,可能就很难恢复。所以我们需要谨慎地设计数据库结构并使用事务进行操作,确保数据的完整性和一致性。
- IndexedDB 不支持跨域,所以我们只能对当前域内的数据进行存储和管理。
- IndexedDB 的兼容性不太好,使用 IndexedDB 存储数据需要注意浏览器的兼容性问题。
总结
本文介绍了在 PWA 中使用 IndexedDB 进行数据存储和管理的方法,讲解了 IndexedDB 的基本概念和常用操作,并指出了使用 IndexedDB 应注意的一些要点。通过学习本文的内容,你已经可以初步掌握 IndexedDB 在 PWA 中的使用方法,从而为你的 PWA 应用提供强大的数据存储和管理能力。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6486d9e248841e989456fc67