本篇要解決的問題
之前寫過存在瀏覽器上的二種方式:Cookies、LocalStorage。本篇要寫的是第三種方式: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');
});
如果懶得寫程式,瀏覽器上如 Chrome、Edge 上也可以直接看到。
在隨便一個網頁上點右鍵按「檢查」,出現的面版上,選單點擊「應用程式」,再選擇「儲存空間」就可以看到了,畫面會像這樣:
安裝 IDB-Keyval
安裝方式很簡單,就跟一般我們要引用 JS 套件一樣。
npm
$ npm install idb-keyval
// 或
$ yarn add idb-keyval
import { get, set } from 'idb-keyval';
CDN
<script type="module">
import { get, set } from 'https://cdn.jsdelivr.net/npm/idb-keyval@6/dist/index.min.js';
</script>
建立資料 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));
可以看到存進去的資料如下:
抓取資料 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);
});
entries
是取得資料表裡的所有資料,返回的值會是陣列:[key, value]
。
import { entries } from 'idb-keyval';
entries().then((entries) => console.log(entries));
// => [["Boolean", true], ["String", "Lets Write"], ... ]
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"]
更新資料 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));
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();
客製資料庫名稱 createStore
如果沒有指定資料庫的名稱,預設的資料庫會是「keyval-store > keyval」。
用 createStore
就可以為資料庫取名稱。
import { createStore } from 'idb-keyval';
const customStore = createStore('客製 DB 名稱', '客製 store 名稱');
用了 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));
Demo 及原始碼
Demo 及原始碼都放在 GitHub 上了,取用之前麻煩分享本篇或在 GitHub 上按個星星,你的小小動作對本站都是大大的鼓勵。
Demo:https://letswritetw.github.io/letswrite-client-storage/
原始碼:https://github.com/letswritetw/letswrite-client-storage
Top comments (0)