随着浏览器的功能不断增强,越来越多的网站开始考虑将大量的数据存储在客户端,相比后端接口,获取数据更快一些。但摆在我们眼前的现状是这样的:
现有的浏览器存储方案都不适合存储大量的数据。 Cookie的大小不超过4KB,而且每次请求都会发送到服务器。 LocalStorage在2.5~10MB之间,浏览器不同,存储的大小还不一样,而且不提供搜索功能,也不能建立自定义索引...
因此,LocalStorage
已经满足不了大量数据本地储存的需求了。于是,很多开发者看向了 IndexedDB
,这是一种可以本地存储大量数据的方法。
在你准备用原生indexedDB
之前,不妨先看看如下这些问题:
我第一次使用IndexDB
时,也是直接使用的IndexedDB API。嗯~嗯~非常麻烦,需要写很多代码,突然感觉还是 LocalStorage 来得简单直接。
怎么解决呢?后来发现了 Dexie.js
。
Dexie.js
,是一个强大、简单的 JavaScript 库,它对浏览器IndexexDB 进行了封装,我们可以很轻松地管理浏览器端的数据。
网上有很多对IndexedDB原生接口进行包装的其它库,但相较而言,Dexie.js
具有以下明显的优点:
和 IndexedDB 原生 API 一样,Dexie.js
的操作也是异步的。但几乎所有Dexie.js
接口都返回promise,也支持链式调用。或者使用 async/await 语法来更清晰地处理异步操作。此外,错误可以在catch中统一处理,且有丰富的错误类型返回。对于我们开发者来说,更加直观友好,编写和维护代码更加优雅方便。
Dexie.js
支持复杂的查询操作,包括过滤、排序、范围查询等,完全不需要编写那些的低级 IndexedDB 代码。还有更丰富的索引定义,并且支持多值索引和复合索引。整个数据的检索和处理非常优雅灵活。
Dexie.js 支持主流的现代浏览器,包括 Chrome、Firefox、Edge 和 Safari 等,手机端上也得到了很多的支持,不用担心兼容性问题。
Dexie.js 是一个轻量级的库,体积小巧,加载速度快,没有其他依赖。
我们可以从 CDN 引入 js 文件。
<script src="https://unpkg.com/dexie@latest/dist/dexie.js"></script>
或者可以使用 npm 或 yarn 来进行安装。
npm install dexie
// or
yarn add dexie
Dexie.js
提供了丰富完善的文档,还针对主流框架提供了使用指南。
由于目前只有英文文档,这里给大家举个简单的使用示例。我示例中使用的是React框架。
在React中使用Dexie.js
,还需要引入一个hooks。
yarn add dexie-react-hooks
接着,获取一个数据库实例
import Dexie from 'dexie';
var db = new Dexie("前端实验室")
// 这里的"前端实验室"是我们数据库的名称
然后,定义表结构
db.version(1).stores({
friends: "++id, &name, age, email",
books: "id, author, name, *categories"
})
ps:注意这里属性字段之前的符号:++,说明是自增的主键;&,说明是唯一索引;,说明该字段是多值索引。*
再下一步,添加数据。这里,我们给"friends"添加数据,先来写个组件
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>
</>
}
使用上面组件添加数据后,后面就是查询数据的操作。查询好友列表中有哪些人。
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()
子句运算符查询多条目索引对象,如:
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 已经满足不了的项目
,你就该考虑它了。