1. 前言
最近剛?cè)肼氃诳葱马?xiàng)目的代碼,學(xué)習(xí)了很多新的代碼封裝思路和模塊化的思想。而且也了解到了IndexedDB數(shù)據(jù)庫(kù)的使用方法,開(kāi)一篇文章來(lái)總結(jié)下IndexedDB在項(xiàng)目中的使用。
2. IndexedDB
2-1. IndexedDB是什么
通俗地說(shuō),IndexedDB就是瀏覽器提供的本地?cái)?shù)據(jù)庫(kù),它可以被網(wǎng)頁(yè)腳本創(chuàng)建和操作。
2-2. 為什么要使用它
以往做網(wǎng)頁(yè)存儲(chǔ),我們一般使用cookie和localStorage或者sessionStorage。但是這兩種方法一個(gè)存儲(chǔ)的空間有限,一個(gè)也只能建立很簡(jiǎn)單的對(duì)象設(shè)置和獲取屬性。而IndexedDB不僅能存儲(chǔ)大量數(shù)據(jù),而且還能建立索引和提供查找接口。在大型項(xiàng)目中會(huì)有很大的優(yōu)勢(shì)。
關(guān)于
IndexedDB的特點(diǎn)和基本概念阮老師的博客寫(xiě)的很清楚。我這里不做概述。本篇文章只是為了記錄下我現(xiàn)在的項(xiàng)目中是如何使用IndexedDB,介紹基本的使用方法。瀏覽器數(shù)據(jù)庫(kù)
3. 使用方法
3-1. 打開(kāi)或者新建數(shù)據(jù)庫(kù)
// 獲取indexedDB數(shù)據(jù)對(duì)象
const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB
// 打開(kāi)或者新建數(shù)據(jù)庫(kù)
/**
* @param {string} databaseName: 打開(kāi)/新建的數(shù)據(jù)庫(kù)名稱(chēng)
* @param {string} version: 數(shù)據(jù)庫(kù)版本號(hào)
*/
let dbRequest = window.indexedDB.open(databaseName, version);
3-2. 設(shè)置不同的處理方法
打開(kāi)數(shù)據(jù)庫(kù)后我們能拿到一個(gè)IndexDBRequest對(duì)象,這個(gè)對(duì)象有三個(gè)處理事件的方法,來(lái)處理打開(kāi)或者新增數(shù)據(jù)庫(kù)的操作結(jié)果
- success事件
dbRequest.onsuccess = event => {
console.log("數(shù)據(jù)庫(kù)打開(kāi)成功");
// 數(shù)據(jù)庫(kù)的實(shí)例對(duì)象
const db = event.target.result;
}
- error事件
dbRequest.onerror = event => {
console.log("數(shù)據(jù)庫(kù)打開(kāi)失敗");
}
- upgradeneeded事件
- 對(duì)于打開(kāi)數(shù)據(jù)庫(kù)來(lái)說(shuō)如果指定的版本大于數(shù)據(jù)庫(kù)的實(shí)際版本就會(huì)這個(gè)數(shù)據(jù)庫(kù)升級(jí)事件,一般來(lái)說(shuō)不會(huì)處理這個(gè)
// 打開(kāi)已有數(shù)據(jù)庫(kù)如果指定的version高于當(dāng)前數(shù)據(jù)的version
window.indexedDB.open(databaseName, version);
dbRequest.onupgradeneeded = event => {
console.log("數(shù)據(jù)庫(kù)需要升級(jí)");
}
- 對(duì)于新建數(shù)據(jù)庫(kù),沒(méi)有版本,新建的時(shí)候就會(huì)直接觸發(fā)這個(gè)事件,通常我們會(huì)在這個(gè)事件中區(qū)新增數(shù)據(jù)庫(kù)表和索引。
dbRequest.onupgradeneeded = event => {
// 通過(guò)事件對(duì)象的`target.result`創(chuàng)建新的數(shù)據(jù)庫(kù)表
const db = event.target.result;
// 創(chuàng)建前先判斷該數(shù)據(jù)庫(kù)表是否存在
if (!db.objectStoreNames.contains("test")) {
// 創(chuàng)建名為`test`的數(shù)據(jù)庫(kù)表并指定主鍵為`id`
let objectStore = db.createObjectStore("test", { keyPath: "id" });
// 如果數(shù)據(jù)記錄里面沒(méi)有合適作為主鍵的屬性,那么可以讓 IndexedDB 自動(dòng)生成主鍵。
// let objectStore = db.createObjectStore("test", { autoIncrement: true });
// 創(chuàng)建索引
/**
* @param {string} 索引名稱(chēng)
* @param {string} 索引所在的屬性
* @param {object} 配置對(duì)象: 說(shuō)明該屬性是否包含重復(fù)的值
*/
objectStore.createIndex("id", "id", { unique: true });
objectStore.createIndex("value", "value", { unique: true });
}
};
3-3. 操作數(shù)據(jù)
操作數(shù)據(jù)分為新增,讀取,更新,刪除等。這些操作都需要通過(guò)事務(wù)完成。
// 打開(kāi)數(shù)據(jù)庫(kù)開(kāi)始操作數(shù)據(jù)
dbRequset.onsuccess = event => {
// 新建事務(wù)
// 新建時(shí)必須指定表格名稱(chēng)和操作模式("只讀"或"讀寫(xiě)")
const trans = db.transaction(["test"], "readwrite");
// 拿到IDBObjectStore對(duì)象
const dictStore = trans.objectStore("test");
// 通過(guò)IDBObjectStore對(duì)象操作數(shù)據(jù)
// 讀取數(shù)據(jù)
const getResp = disStore.get("1");
// 新增數(shù)據(jù)
const addResp = disStore.add({ id: 1, value: "test"});
// 更新數(shù)據(jù)
const putResp = disStore.put({ id: 1, value: "test1"});
// 刪除數(shù)據(jù)
const deleteResp = disStore.delete(1);
// 上述幾種操作數(shù)據(jù)庫(kù)的方法都會(huì)返回一個(gè)連接對(duì)象
// 通過(guò)監(jiān)聽(tīng)返回的連接對(duì)象來(lái)判斷是否操作成功
getResp.onerror = function(event) {
console.log('事務(wù)失敗');
};
getResp.onsuccess = function( event) {
if (request.result) {
console.log('value: ' + request.result.value);
} else {
console.log('未獲得數(shù)據(jù)記錄');
}
};
}
3-4. 使用索引
我們?cè)谏厦鎸?duì)value字段建立了索引
objectStore.createIndex("value", "value", { unique: true });
所以我們可以通過(guò)索引value去查找數(shù)據(jù)了
// 也要先創(chuàng)建事務(wù)指定為只讀
const trans = db.transaction(["test"], "readonly");
// 拿到IDBObjectStore對(duì)象
const dictStore = trans.objectStore("test");
// 拿到連接對(duì)象
let request = dictStore.index("value").get("test");
request.onsuccess = function(event) {
if (event.target.result) {
console.log(event.target.result);
} else {
console.log('未獲得數(shù)據(jù)記錄');
}
};
最近項(xiàng)目中用到了很多新技術(shù),微前端,發(fā)布組件,瀏覽器數(shù)據(jù)庫(kù)等等,我目前也在一邊學(xué)習(xí)一邊總結(jié)。如果這篇文章對(duì)大家有幫助的話點(diǎn)個(gè)贊唄????