likes
comments
collection
share

丢芝麻localStorage捡西瓜localforage、IndexedDB

作者站长头像
站长
· 阅读数 11

在日常开发中,前端常用的存储都是cookies、Web Storage(sessionStorage、localStorage),虽然使用简单,但也存在两个明显的弊端。

  1. 存储空间限制:cookies 4Kb,sessionStorage、localStorage 一般是5M,对于存储更大量的结构化数据来说力不从心
  2. 存取不便:存入的内容需要经过序列化,取值的时候需要通过反序列化

而 IndexedDB 提供了这种场景的解决方案,localforage则使得IndexedDB用起来可以像Web Storage一样简单

IndexedDB

如果你觉得了解IndexedDB太麻烦,那么可以选择跳过,直接到下一节localforage😹😹😹

IndexedDB 优势

IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。

存取方便

IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。然而,不像 RDBMS 使用固定列表。

IndexedDB 是一个基于 JavaScript 的面向对象数据库,允许您存储和检索用键索引的对象,可以存储结构化克隆算法支持的任何对象,不需要经过序列化与反序列化。如下

丢芝麻localStorage捡西瓜localforage、IndexedDB 存储空间大

IndexedDB 的储存空间并没有做限制。

异步存取

localStorage如果存储内容多的话会消耗内存空间,会导致页面变卡。而IndexedDB执行的操作是异步执行的,不会阻塞应用程序,可在Web Worker 使用。

兼容性好

配合localforage的优雅降级策略(后面补充),兼容性这一块完全不用操心,大胆用就对了👏👏👏👏 丢芝麻localStorage捡西瓜localforage、IndexedDB

IndexedDB简单的使用

链接/创建库

let db = null;
const dbName = "testDB",
storeName = "testStore";
const openDB = () => {
  // 链接数据库,不存在则创建
  const DBOpenRequest = window.indexedDB.open(dbName);
  DBOpenRequest.onsuccess = function (event) {
    db = event.target.result;
  };
  DBOpenRequest.onerror = function () {
    console.log("数据库打开报错");
  };
  DBOpenRequest.onupgradeneeded = function (event) {
    // 数据库创建或升级的时候会触发
    db = event.target.result;
    // 创建对象库,即存储表
    db.createObjectStore(storeName, {
      keyPath:'key' ,
    });
  };
};

添加数据

const addData = () => {
  let objectStoreRequest = db
    .transaction([storeName], "readwrite") // 事务对象 指定表格名称和操作模式("只读"或"读写")
    .objectStore(storeName) // 仓库对象
    .add({
      key: "Walk dog",
      hours: 19,
      minutes: 30,
      day: 24,
      month: "December",
      year: 2014,
      notified: "no",
    });

  objectStoreRequest.onsuccess = function () {
    console.log("数据写入成功");
  };

  objectStoreRequest.onerror = function (event) {
    console.log("数据写入失败");
    throw new Error(event.target.error);
  };
};

查询获取数据

 const getData = ()=> {
  let transaction = db.transaction([storeName], "readwrite"); // 事务
  let objectStore = transaction.objectStore(storeName); // 仓库对象
  let request = objectStore.get("Walk dog");

  request.onerror = function (event) {
    console.log("事务失败");
  };

  request.onsuccess = function (event) {
    console.log("主键查询结果: ", request.result);
  };  
}

修改数据

const updateData = ()=> {
  let transaction = db.transaction([storeName], "readwrite"); // 事务
  let objectStore = transaction.objectStore(storeName); // 仓库对象
  let request = objectStore.get("Walk dog2");  // 获取key值为Walk dog2的数据

  request.onerror = function (event) {
    console.log("事务失败");
  };
  request.onsuccess = function (event) {
    const data = request.result || {key:'Walk dog2'};  // 如果不存在,则创建
    console.log("主键查询结果: ", data);
    data.notified = "yes";
    const updateRequest = objectStore.put(data);  // 入库修改
    updateRequest.onsuccess = () => {
      console.log("修改成功 ");
    };
  };
}

删除数据

function deleteData() {
    let request = db.transaction([storeName],'readwrite').objectStore(storeName).delete('Walk dog2')

    request.onsuccess = function () {
        console.log('数据删除成功')
    }

    request.onerror = function () {
        console.log('数据删除失败')
    }
}

更多API可参考文档直通车

看到这,是不是有那么些放弃的想法了🤣🤣。兄嘚,莫要捉急,以下通过localforage实现更简单的操作🤔🤔🤔

localforage

localForage 是一个 JavaScript 库,通过简单类似 localStorage API 的异步存储来改进你的 Web 应用程序的离线体验。它能存储多种类型的数据,而不仅仅是字符串。

localForage 有一个优雅降级策略,若浏览器不支持 IndexedDB 或 WebSQL,则使用 localStorage。在所有主流浏览器中都可用:Chrome,Firefox,IE 和 Safari(包括 Safari Mobile)

安装

npm install localforage

改进的离线存储

// 通过 localStorage 设置值
localStorage.setItem('key', JSON.stringify('value')); 
doSomethingElse(); 

// 通过 localForage 完成同样功能 
localforage.setItem('key', 'value').then(doSomethingElse); 
// localForage 同样支持回调函数 
localforage.setItem('key', 'value', doSomethingElse);

//取值
localforage.getItem('key').then((value)=>{
console.log(value)
})

// 删除
localforage.removeItem('key').then(function() { // 当值被移除后,此处代码运行 
console.log('Key is cleared!');
})

//从数据库中删除所有的 key,重置数据库
localforage.clear().then(function() { // 当数据库被全部删除后,此处代码运行 
  console.log('Database is now empty.'); 
})

配置(可选)

设置 localForage 选项,详见文档

localforage.config({
  //按顺序使用的首选驱动,默认值:[localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE]
  driver: [localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE],
  // 数据库的名称,默认值:'localforage'
  name: "localforageTest", 
  //数据仓库的名称,默认值:'keyvaluepairs'
  storeName: "localforageStore", 
  //数据库的大小(以字节为单位)。现在只用于WebSQL。 默认值:4980736
  size: 1024 * 500, 
  //数据库的版本。将来可用于升级; 目前未使用。默认值:1.0
  version: 1.0, 
  //数据库的描述,一般是提供给开发者的。默认值:''
  description: "", 
});

配置完后添加数据,如下

丢芝麻localStorage捡西瓜localforage、IndexedDB

创建多个实例

当直接使用localforage时,会默认创建并使用实例。

createInstance:创建并返回一个 localForage 的新实例。每个实例对象都有独立的数据库,而不会影响到其他实例。

const store1 = localforage.createInstance({
  name: "store1",
  storeName: "localforageStore1",
});

const store2 = localforage.createInstance({
  name: "store2",
  storeName: "localforageStore2",
});
const store3 = localforage.createInstance({
  name: "store2",
  storeName: "localforageStore3",
});
store1.setItem('store1key',{myKey:'myValue'})
store2.setItem('store2key',{myKey:'myValue'})
store3.setItem('store3key',{myKey:'myValue'})

丢芝麻localStorage捡西瓜localforage、IndexedDB

实例删除

dropInstance:

  1. 调用时,若不传参,将删除当前实例的 “数据仓库” 。
  2. 调用时,若参数为一个指定了 name 和 storeName 属性的对象,会删除指定的 “数据仓库”。
  3. 调用时,若参数为一个仅指定了 name 属性的对象,将删除指定的 “数据库”(及其所有数据仓库)。
  localforage.dropInstance()
  localforage.dropInstance({
    name: "store1",
  })
  localforage.dropInstance({
    name: "store2",
    storeName:'localforageStore3'
  })

到这,相信你已经学会了localforage了👏👏👏👏

当然,你也可以结合其他状态管理工具(Pinia,vuex,mobx等)实现更高级的封装与使用😎😎😎