Vue IndexedDB 入门 idb idb-keyval 取代 Localstorage
2021-06-07
阅读 {{counts.readCount}}
评论 {{counts.commentCount}}
## 前言
早些年学网页编程,还都是后端渲染,前段多数时候只负责内容排版,样式优化等,
近几年前端技术突飞猛进发展,对于数据缓存的需求变得非常重要。
<br>
`Localstorage` 目前仍是前段缓存数据的主流方案。
但 `Localstorage` 的 同步读写、只支持 `String`、总大小有限等机制,限制了他的使用场景。
非常需要一款更大型的,支持复杂数据结构,支持各种数据类型、异步增删改查的前端数据库!
<br>
`IndexedDB` 就是这样一个存在。
本文将基于 `idb` `idb-keyval` 这2个 `IndexedDB` js库实现简单功能入门笔记。
<br>
提前先说下如何调试 `IndexedDB` , 和 `Localstorage` 一样
在调试工具 - `Application` - `Storage` - `IndexedDB` 中可以看到数据库、表、字段、数据
<br><br>
## 入门款
idb-keyval 是一个入门款方案,把 IndexedDB 模拟成了 key-val 类型库,用法非常接近于 `Localstorage` 或 `Redis`
[https://www.npmjs.com/package/idb-keyval](https://www.npmjs.com/package/idb-keyval)
[https://github.com/jakearchibald/idb-keyval](https://github.com/jakearchibald/idb-keyval)
基础用法例子
```shell
npm install idb-keyval
```
<br>
```javascript
import { get, set } from 'idb-keyval';
// 保存数据 (异步)
set('key', 'value')
.then(() => console.log('success'))
.catch((err) => console.log('error', err));
// 获取数据 (异步)
get('hello').then((val) => console.log(val));
```
<br>
几乎和 `Localstorage` 如出一辙
好处是:异步增加读写效率,数据类型可以是任意的,且数据大小限制远超过 `Localstorage` ,可以是一张图片或任意格式文件,可以是 `Number` 、 `String` 、 `Array` 、 `Object` 等等,取出数据不需要再次转换格式
缺点是:没有发挥出 `IndexedDB` 的完整实力,且有点不伦不类
<br>
原理就是在 `IndexedDB` 中建了一张表,keyval-store,一共2个字段,key value,key字段加唯一索引,类似于使用 `MongoDB` / `MySql` 模拟 `Redis`
<br><br>
## 满血版
idb 和 idb-keyval 出自同一个作者,而idb是满血版,可实现所有indexeddb功能,且简化了繁琐流程
[https://www.npmjs.com/package/idb](https://www.npmjs.com/package/idb)
[https://github.com/jakearchibald/idb](https://github.com/jakearchibald/idb)
<br>
BUT!!!
但是!!!
idb对我来说依旧是过于难学哈哈,学的头秃
![](/api/file/getImage?fileId=60efe1dbda74050013001554)
<br><br>
于是我找了个bilibili up主的教程从头学了一遍,发现一个更容易学的 `IndexedDB` 库
**`Dexie`** !!! YYDS
[https://www.bilibili.com/video/BV15J411H7GH](https://www.bilibili.com/video/BV15J411H7GH)
[https://github.com/dfahlander/Dexie.js](https://github.com/dfahlander/Dexie.js)
[https://www.npmjs.com/package/dexie](https://www.npmjs.com/package/dexie)
建议各位直接看这个up主的教程,包学包会
<br><br>
我就直接放几个在 `Vue-cli` 中的简单用法
```shell
npm install dexie
```
新建一个目录 `database`
目录的下面新建一个文件 `index.js`
```javascript
import Dexie from 'dexie';
const databaseName = "database_name";
const databaseVersion = 1;
// 初始化数据库
const database = new Dexie(databaseName);
// 按版本 初始化表和字段
database.version(databaseVersion).stores({
table: "id,name,age,email,createTime"
});
/** 添加或更新 一条数据*/
export function putData(object){
database.table.put(object);
}
/** 批量添加或更新数据 */
export function putDatas(array){
database.table.bulkPut(array);
}
/** 删除一条数据 */
export function deleteData(key){
database.table.delete(key);
}
/** 查询一条数据 */
export async function getData(key) {
return await database.table.get(key);
}
/** 查询所有数据 */
export async function getDatas(i,n) {
// 创建时间倒序 (由于没有倒序 自己加个reverse就是倒序)
// 这里我为了配合分页,加了offset limit 结合起来就是MySql的limit(i,n) 不需要的话也可以直接去掉
return await database.table.orderBy("createTime").reverse().offset(i).limit(n).toArray();
}
/** 查询数据个数 */
export async function getCount() {
return await database.table.count();
}
export default {
putData,
putDatas,
deleteData,
getData,
getDatas,
getCount
}
```
最后在需要用到的地方
```javascript
import database from "../database";
const datas = new Array();
datas.push({id: "id", name: "name", age: 1, email: "email", createTime: new Date().getTime()});
// 批量插入数据
database.putDatas(datas);
// 有返回值的地方一律用then异步拿返回值
database.getCount().then(count => {
// ...
});
database.putDatas(index, number).then(datas => {
// ...
});
```
## END