前言

早些年学网页编程,还都是后端渲染,前段多数时候只负责内容排版,样式优化等,
近几年前端技术突飞猛进发展,对于数据缓存的需求变得非常重要。


Localstorage 目前仍是前段缓存数据的主流方案。
Localstorage 的 同步读写、只支持 String、总大小有限等机制,限制了他的使用场景。
非常需要一款更大型的,支持复杂数据结构,支持各种数据类型、异步增删改查的前端数据库!


IndexedDB 就是这样一个存在。
本文将基于 idb idb-keyval 这2个 IndexedDB js库实现简单功能入门笔记。


提前先说下如何调试 IndexedDB , 和 Localstorage 一样
在调试工具 - Application - Storage - IndexedDB 中可以看到数据库、表、字段、数据



入门款

idb-keyval 是一个入门款方案,把 IndexedDB 模拟成了 key-val 类型库,用法非常接近于 LocalstorageRedis
https://www.npmjs.com/package/idb-keyval
https://github.com/jakearchibald/idb-keyval

基础用法例子

  1. npm install idb-keyval


  1. import { get, set } from 'idb-keyval';
  2. // 保存数据 (异步)
  3. set('key', 'value')
  4. .then(() => console.log('success'))
  5. .catch((err) => console.log('error', err));
  6. // 获取数据 (异步)
  7. get('hello').then((val) => console.log(val));


几乎和 Localstorage 如出一辙
好处是:异步增加读写效率,数据类型可以是任意的,且数据大小限制远超过 Localstorage ,可以是一张图片或任意格式文件,可以是 NumberStringArrayObject 等等,取出数据不需要再次转换格式
缺点是:没有发挥出 IndexedDB 的完整实力,且有点不伦不类

原理就是在 IndexedDB 中建了一张表,keyval-store,一共2个字段,key value,key字段加唯一索引,类似于使用 MongoDB / MySql 模拟 Redis



满血版

idb 和 idb-keyval 出自同一个作者,而idb是满血版,可实现所有indexeddb功能,且简化了繁琐流程
https://www.npmjs.com/package/idb
https://github.com/jakearchibald/idb


BUT!!!
但是!!!
idb对我来说依旧是过于难学哈哈,学的头秃



于是我找了个bilibili up主的教程从头学了一遍,发现一个更容易学的 IndexedDB
Dexie !!! YYDS
https://www.bilibili.com/video/BV15J411H7GH
https://github.com/dfahlander/Dexie.js
https://www.npmjs.com/package/dexie

建议各位直接看这个up主的教程,包学包会



我就直接放几个在 Vue-cli 中的简单用法

  1. npm install dexie

新建一个目录 database
目录的下面新建一个文件 index.js

  1. import Dexie from 'dexie';
  2. const databaseName = "database_name";
  3. const databaseVersion = 1;
  4. // 初始化数据库
  5. const database = new Dexie(databaseName);
  6. // 按版本 初始化表和字段
  7. database.version(databaseVersion).stores({
  8. table: "id,name,age,email,createTime"
  9. });
  10. /** 添加或更新 一条数据*/
  11. export function putData(object){
  12. database.table.put(object);
  13. }
  14. /** 批量添加或更新数据 */
  15. export function putDatas(array){
  16. database.table.bulkPut(array);
  17. }
  18. /** 删除一条数据 */
  19. export function deleteData(key){
  20. database.table.delete(key);
  21. }
  22. /** 查询一条数据 */
  23. export async function getData(key) {
  24. return await database.table.get(key);
  25. }
  26. /** 查询所有数据 */
  27. export async function getDatas(i,n) {
  28. // 创建时间倒序 (由于没有倒序 自己加个reverse就是倒序)
  29. // 这里我为了配合分页,加了offset limit 结合起来就是MySql的limit(i,n) 不需要的话也可以直接去掉
  30. return await database.table.orderBy("createTime").reverse().offset(i).limit(n).toArray();
  31. }
  32. /** 查询数据个数 */
  33. export async function getCount() {
  34. return await database.table.count();
  35. }
  36. export default {
  37. putData,
  38. putDatas,
  39. deleteData,
  40. getData,
  41. getDatas,
  42. getCount
  43. }

最后在需要用到的地方

  1. import database from "../database";
  2. const datas = new Array();
  3. datas.push({id: "id", name: "name", age: 1, email: "email", createTime: new Date().getTime()});
  4. // 批量插入数据
  5. database.putDatas(datas);
  6. // 有返回值的地方一律用then异步拿返回值
  7. database.getCount().then(count => {
  8. // ...
  9. });
  10. database.putDatas(index, number).then(datas => {
  11. // ...
  12. });

END