DEV Community

Cover image for 使用 IndexedDB 實現 Client 端數據存儲 – 前端工程師必學的 Web Storage 技術(第三篇)
Let's Write
Let's Write

Posted on • Edited on • Originally published at letswrite.tw

使用 IndexedDB 實現 Client 端數據存儲 – 前端工程師必學的 Web Storage 技術(第三篇)

本篇要解決的問題

之前寫過存在瀏覽器上的二種方式:CookiesLocalStorage。本篇要寫的是第三種方式:IndexedDB,主要會寫的是推薦套件的使用,IndexedDB 介紹或原理不會寫,因為找資料時有看到幾篇寫的很詳細的教學文了(絕對不會說是太懶)

本篇推薦的套件是:IDB-Keyval,簡單好用,檔案大小甚至不到 1KB,真的是居家旅行必備良藥。

推薦參考文章:

最後完成的 Demo 會在這:

https://letswritetw.github.io/letswrite-client-storage/


限制

  • 限制大小:約 250 MB (可檢測,詳見下段)
  • 限制期限:要主動刪除或程式刪除
  • 資料格式:除了純值,也可存 Array、Object、Date、Blob 等

檢測瀏覽器儲存空間大小

在開始使用 IDB 之前,先提供一個 function,可以知道瀏覽器提供的儲存空間有多少:

navigator.storage.estimate().then((estimate) => { console.log('總配額', Math.round(estimate.quota * 0.000001) + ' MB') console.log('已使用', Math.round(estimate.usage * 0.000001) + ' MB'); }); 
Enter fullscreen mode Exit fullscreen mode

如果懶得寫程式,瀏覽器上如 Chrome、Edge 上也可以直接看到。

在隨便一個網頁上點右鍵按「檢查」,出現的面版上,選單點擊「應用程式」,再選擇「儲存空間」就可以看到了,畫面會像這樣:

Chrome 儲存空間

Edge 儲存空間


安裝 IDB-Keyval

安裝方式很簡單,就跟一般我們要引用 JS 套件一樣。

npm

$ npm install idb-keyval // 或 $ yarn add idb-keyval 
Enter fullscreen mode Exit fullscreen mode
import { get, set } from 'idb-keyval'; 
Enter fullscreen mode Exit fullscreen mode

CDN

<script type="module"> import { get, set } from 'https://cdn.jsdelivr.net/npm/idb-keyval@6/dist/index.min.js'; </script> 
Enter fullscreen mode Exit fullscreen mode

建立資料 set、setMany

set 用在一次儲存一筆資料,setMany 用在一次要儲存多筆資料。

值接受的格式,文件上是說都支援,像是 Number、Array、Object、Date、Blob 等等。

只是遇到上古神獸的話(如 IE),有些值會不支援,但都是上古神獸了,就讓它存在我們的回憶裡吧。

import { set, setMany } from 'idb-keyval'; // set set('String', 'Lets Write') .then(() => console.log('set 儲存成功')) .catch((err) => console.log('set 儲存失敗', err)); // setMany setMany([ ['Boolean', true], ['Number', 1234567890], ['Date', new Date()], ['Object', { 'Author': 'August' }], ['Array', [1, 2, 3]] ]).then(() => console.log('setMany 儲存成功')) .catch((err) => console.log('setMany 儲存失敗', err)); 
Enter fullscreen mode Exit fullscreen mode

可以看到存進去的資料如下:

儲存資料


抓取資料 get、getMany、entries、keys、values

get 是取一筆,getMany 是取多筆。

import { get, getMany } from 'idb-keyval'; // get get('String').then((val) => console.log(val)); // getMany getMany(['Boolean', 'Date', 'Object']).then(([v1, v2, v3]) => { console.log(v1); console.log(v2); console.log(v3); }); 
Enter fullscreen mode Exit fullscreen mode

entries 是取得資料表裡的所有資料,返回的值會是陣列:[key, value]

import { entries } from 'idb-keyval'; entries().then((entries) => console.log(entries)); // => [["Boolean", true], ["String", "Lets Write"], ... ] 
Enter fullscreen mode Exit fullscreen mode

keys 是取得所有的 key,values 是取得所有的 value。

import { keys, values} from 'idb-keyval'; // keys keys().then((keys) => console.log(keys)); // => ["Array", "Boolean", "Date", "Number", "Object", "String"] // values values().then((values) => console.log(values)); // => [[1, 2, 3], true, "2022-12-27T20:10:05.521Z", 1234567890, {"Author": "August" }, "Lets Write"] 
Enter fullscreen mode Exit fullscreen mode

更新資料 update

update 同時包含了 set、get,它的主要使用情境是:不確定 IDB 有沒有存某個值,有的話就更新,沒有的話就不理。

如果沒有 update,我們就得先用 get 確認資料是否存在,接著再用 set 去覆寫資料。

有了 update,我們就可以寫成以下:

import { update } from 'idb-keyval'; update('Array', function(val){ console.log(val); return [4, 5, 6] }).then(() => console.log('update 成功')) .catch((err) => console.log('update 失敗', err)); 
Enter fullscreen mode Exit fullscreen mode

console.log(val) 可以看到原本的值,return 則是寫入新值。


刪除資料 del、delMany、clear

del 是刪一筆,delMany 是刪多筆,clear 是把資料表整個清空。

// del del('String') .then(() => console.log('del 刪除成功')); // delMany delMany(['Date', 'Object']) .then(() => console.log('delMany 成功')) .catch((err) => console.log('delMany 失敗', err)); // clear clear(); 
Enter fullscreen mode Exit fullscreen mode

客製資料庫名稱 createStore

如果沒有指定資料庫的名稱,預設的資料庫會是「keyval-store > keyval」。

createStore 就可以為資料庫取名稱。

import { createStore } from 'idb-keyval'; const customStore = createStore('客製 DB 名稱', '客製 store 名稱'); 
Enter fullscreen mode Exit fullscreen mode

用了 createStore 後,在執行讀寫資料時,就要多指定是要存進哪個資料庫裡。

import { createStore, set } from 'idb-keyval'; const CustomIDB = createStore('LetsWrite', 'GoodStore'); // set set('String-Custom', 'Lets Write Happy New Year~', CustomIDB); // get get('String-Custom', CustomIDB).then((val) => console.log(val)); // entries entries(CustomIDB).then((entries) => console.log('CustomIDB entries', entries)); 
Enter fullscreen mode Exit fullscreen mode

Demo 及原始碼

Demo 及原始碼都放在 GitHub 上了,取用之前麻煩分享本篇或在 GitHub 上按個星星,你的小小動作對本站都是大大的鼓勵。

Demo:https://letswritetw.github.io/letswrite-client-storage/

原始碼:https://github.com/letswritetw/letswrite-client-storage


瀏覽器上的儲存空間系列

Top comments (0)