DEV Community

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

Posted on • Updated 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)