LocalStorage不够用?那就该试试这个

2023-11-16 15:43:30 浏览数 (1)

前言

随着浏览器的功能不断增强,越来越多的网站开始考虑将大量的数据存储在客户端,相比后端接口,获取数据更快一些。但摆在我们眼前的现状是这样的:

现有的浏览器存储方案都不适合存储大量的数据。 Cookie的大小不超过4KB,而且每次请求都会发送到服务器。 LocalStorage在2.5~10MB之间,浏览器不同,存储的大小还不一样,而且不提供搜索功能,也不能建立自定义索引...

因此,LocalStorage 已经满足不了大量数据本地储存的需求了。于是,很多开发者看向了 IndexedDB,这是一种可以本地存储大量数据的方法。

在你准备用原生indexedDB之前,不妨先看看如下这些问题:

  • 原生所有操作都是在回调中进行的
  • 原生所有操作都需要不断地创建事务,判断表和索引的存在性
  • 原生为表建立索引很繁琐
  • 原生查询支持的较为简单,复杂的查询需要自己去实现
  • 原生不支持批量操作
  • 原生的错误需要在每个失败回调中接收处理
  • ...

我第一次使用IndexDB时,也是直接使用的IndexedDB API。嗯~嗯~非常麻烦,需要写很多代码,突然感觉还是 LocalStorage 来得简单直接。

怎么解决呢?后来发现了 Dexie.js

Dexie.js简介和优势

Dexie.js,是一个强大、简单的 JavaScript 库,它对浏览器IndexexDB 进行了封装,我们可以很轻松地管理浏览器端的数据。

网上有很多对IndexedDB原生接口进行包装的其它库,但相较而言,Dexie.js具有以下明显的优点:

Promise 异步支持

和 IndexedDB 原生 API 一样,Dexie.js的操作也是异步的。但几乎所有Dexie.js接口都返回promise,也支持链式调用。或者使用 async/await 语法来更清晰地处理异步操作。此外,错误可以在catch中统一处理,且有丰富的错误类型返回。对于我们开发者来说,更加直观友好,编写和维护代码更加优雅方便。

简化数据查询

Dexie.js支持复杂的查询操作,包括过滤、排序、范围查询等,完全不需要编写那些的低级 IndexedDB 代码。还有更丰富的索引定义,并且支持多值索引和复合索引。整个数据的检索和处理非常优雅灵活。

浏览器兼容性好

Dexie.js 支持主流的现代浏览器,包括 Chrome、Firefox、Edge 和 Safari 等,手机端上也得到了很多的支持,不用担心兼容性问题。

轻量级

Dexie.js 是一个轻量级的库,体积小巧,加载速度快,没有其他依赖。

Dexie.js 安装使用

安装

我们可以从 CDN 引入 js 文件。

代码语言:javascript复制
<script src="https://unpkg.com/dexie@latest/dist/dexie.js"></script>

或者可以使用 npm 或 yarn 来进行安装。

代码语言:javascript复制
npm install dexie
// or
yarn add dexie
使用

Dexie.js提供了丰富完善的文档,还针对主流框架提供了使用指南。

由于目前只有英文文档,这里给大家举个简单的使用示例。我示例中使用的是React框架。

在React中使用Dexie.js,还需要引入一个hooks。

代码语言:javascript复制
yarn add dexie-react-hooks

接着,获取一个数据库实例

代码语言:javascript复制
import Dexie from 'dexie';
var db = new Dexie("前端实验室")
// 这里的"前端实验室"是我们数据库的名称

然后,定义表结构

代码语言:javascript复制
db.version(1).stores({
    friends: "  id, &name, age, email",
    books: "id, author, name, *categories"
})

ps:注意这里属性字段之前的符号: ,说明是自增的主键;&,说明是唯一索引;,说明该字段是多值索引。*

再下一步,添加数据。这里,我们给"friends"添加数据,先来写个组件

代码语言:javascript复制
export function AddFriendForm() {
  const [name, setName] = useState("");
  const [age, setAge] = useState(18);
  const [email, setEmail] = useState("");
  
  const [status, setStatus] = useState("");

  async function addFriend() {
    try {

      // Add the new friend!
      const id = await db.friends.add({
        name,
        age,
        email
      });

      setStatus(`好友 ${name} 添加成功. id是 ${id}`);
      setName("");
      setAge(18);
      setEmail("");
    } catch (error) {
      setStatus(`添加 ${name} 失败: ${error}`);
    }
  }

  return <>
    <p>
      {status}
    </p>
    Name:
    <input
      type="text"
      value={name}
      onChange={ev => setName(ev.target.value)}
    />
    Age:
    <input
      type="number"
      value={age}
      onChange={ev => setAge(Number(ev.target.value))}
    />
    Email:
    <input
      type="text"
      value={email}
      onChange={ev => setEmail(ev.target.value)}
    />
    Age:
    
    <button onClick={addFriend}>
      添加
    </button>
  </>
}

使用上面组件添加数据后,后面就是查询数据的操作。查询好友列表中有哪些人。

代码语言:javascript复制
export function FriendList() {
  const friends = useLiveQuery(
    () => db.friends.toArray()
  );

  return <ul>
    {friends?.map(friend => <li key={friend.id}>
      {friend.name}, {friend.age}
    </li>)}
  </ul>;
}

这里我们用toArray()查询了所有的好友。此外,我们可以用where() 子句运算符查询多条目索引对象,如:

代码语言:javascript复制
const friends = useLiveQuery(
    () => db.friends
        .where('age')
        .between(18, 28)
        .toArray()
  );

这里就是查询age字段值在18到28之间的好友。其他查询条件还有above(),aboveOrEqual(),anyOf()below()equals()等。更多内容,请查阅下方链接。

官方地址: https://dexie.org/

小结

Dexie.js 提供简洁的 API,让我们可以轻松创建、打开、查询和管理 IndexedDB 数据库。我们不仅可以定义数据模式,包括表格和索引,而且随着 web 项目的发展迭代,还可以方便地进行数据库版本升级。

有了前边的示例,想必大家能明白 Dexie.js 的适用场景了。尤其是那些 LocalStorage 已经满足不了的项目,你就该考虑它了。

0 人点赞