VUE - IndexDB瀏覽器數據庫做緩存
前端開發時經常有瀏覽器做緩存的需求,但是其他緩存容量都比較小,只有幾K到幾M
如有大數據,或者文件要做緩存存儲在瀏覽器端,則考虛用瀏覽器數據庫IndexDB,存儲無上限。
各緩存比較:https://www.cnblogs.com/ccv2/p/13046768.html
1. 本文以 VUE 項目為例,在 app.vue中引入 test2.vue ,調用 utils / uIndexDB.js 工具組件
2. 關鍵代碼
1) 定義 indexDB
const indexDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
2) 緩存類 IndexDBCache
class IndexDBCache { //構造函數 constructor(callback) { this._db = null; //數據庫 this._transaction = null; //事務 this._request = null; this._dbName = 'cacheModel'; //數據庫名 this._cacheTableName = 'tabmodalcache'; //表名 this._dbversion = 1; //數據庫版本 this.DB_Init(callback); //初始化數據庫 }
......
......
...... }
3) 初始化數據庫
//初始化數據庫 DB_Init(callback) { debugger; this._request = indexDB.open(this._dbName, this._dbversion); //數據庫名,版本 this._request.onsuccess = event => { debugger; this._db = this._request.result; let msg = 'indexdb打開成功!' console.log(msg); if (typeof callback === 'function') callback(msg); }; this._request.onerror = event => { debugger; let msg = 'indexdb初始化失敗!' console.log(msg); if (typeof callback === 'function') callback(msg); }; this._request.onupgradeneeded = event => { debugger; let db = this._request.result; if (!db.objectStoreNames.contains(this._cacheTableName)) { let store = db.createObjectStore(this._cacheTableName, { keyPath: 'id', //設置主鍵 autoIncrement: true //自動生成主鍵 }); //創建索引 store.createIndex("INDEX_ID", "id", { unique: true }); //創建索引 store.createIndex('index_senceid', 'senceid', { unique: false, //true:唯一,false:可重復 }); } let msg = 'indexdb升級成功!'; console.log(msg); if (typeof callback === 'function') callback(msg); } }
4)刪除數據庫
//刪除數據庫 DB_Remove(callback) { var DBDeleteRequest = indexedDB.deleteDatabase(this._dbName); DBDeleteRequest.onerror = function (event) { console.log('Error'); }; DBDeleteRequest.onsuccess = function (event) { let msg = 'indexdb刪除成功!'; console.log(msg); if (typeof callback === 'function') callback(msg); }; }
5) 關閉數據庫
//關閉數據庫 DB_Close() { this._db.close(); }
6) 獲取表
//獲取表 Table_Get() { return new Promise((resolve, reject) => { resolve(this._db.objectStoreNames); }); }
7) 新增數據
/** 新增數據 * obj: {path:'Http://xxxxx.com',version:'V1',value:'ccc'} * */ Record_Add(obj) { return new Promise((resolve, reject) => { let transaction = this._db.transaction(this._cacheTableName, 'readwrite'); let store = transaction.objectStore(this._cacheTableName); let response = store.add(obj); response.onsuccess = (cc, mm) => { let msg = `新增數據${JSON.stringify(obj)}` resolve(msg); } response.onerror = (event) => { console.log('新增失敗'); reject(event); } }) }
8) 獲取數據
//獲取數據 Record_Get() { return new Promise((resolve, reject) => { let transaction = this._db.transaction(this._cacheTableName); var objectStore = transaction.objectStore(this._cacheTableName); //主健讀取 // var request = objectStore.get(1); //使用索引讀取 var index = objectStore.index('index_senceid'); var request = index.get('222'); request.onsuccess = () => { resolve(request.result); }; request.onerror = (event) => { console.log('獲取失敗'); reject(event); }; }); }
9) 獲取所有數據
//獲取所有數據 Record_GetAll() { return new Promise((resolve, reject) => { let transaction = this._db.transaction(this._cacheTableName); var objectStore = transaction.objectStore(this._cacheTableName); let request = objectStore.getAll(); request.onsuccess = () => { resolve(request.result); }; request.onerror = (event) => { console.log('獲取失敗'); reject(event); }; }) }
10) 更新數據
/** 更新數據 * obj: {path:'Http://xxxxx.com',version:'V1',value:'fff'} */ Record_Update(obj) { return new Promise((resolve, reject) => { let transaction = this._db.transaction(this._cacheTableName, 'readwrite'); let store = transaction.objectStore(this._cacheTableName); var request = store.put(obj); request.onsuccess = function (event) { let msg = '數據更新成功'; console.log(msg); resolve(msg); }; request.onerror = function (event) { console.log('數據更新失敗'); reject(event); } }); }
11) 刪除數據
//刪除數據 Record_Remove(id) { return new Promise((resolve, reject) => { let transaction = this._db.transaction(this._cacheTableName, 'readwrite'); let store = transaction.objectStore(this._cacheTableName); let response = store.delete(id); response.onsuccess = () => { console.log('刪除成功'); resolve('刪除成功'); } response.onerror = (event) => { console.log('刪除失敗'); reject(event); } }) }
12) 加載網絡文件,以 blob 格式存儲
//加載網絡文件 loadNetSource(url) { return new Promise((resolve, reject) => { fetch(url).then(res => { if (res.status === 200) { res.blob().then(blob => { resolve(blob); }) } else { console.log('未找到緩存資源'); reject(url); } }) }) }
讀取時,使用 URL.createObjectURL() 創建虛擬地址
let _url = URL.createObjectURL(blob);
3. 代碼如下
1) src / APP.vue

<template> <div id="app"> <test></test> </div> </template> <script> import test from "./test2.vue"; export default { name: "app", components: { test }, data() { return { msg: "Welcome to Your Vue.js App", }; }, }; </script> <style> </style>
2) src / test2.vue

<template> <div class="box"> <div class="btnBox"> <button class="btn" @click="fun_db_close">關閉數據庫</button> <button class="btn" @click="fun_db_remove">刪除數據庫</button> </div> <div class="btnBox"> <button class="btn" @click="fun_table_create">創建對象倉庫</button> <button class="btn" @click="fun_table_remove">刪除對象倉庫</button> <button class="btn" @click="fun_table_update">更新對象倉庫</button> <button class="btn" @click="fun_table_get">獲取對象倉庫</button> </div> <div class="btnBox"> <button class="btn" @click="fun_record_create">寫入記錄</button> <button class="btn" @click="fun_record_remove">刪除記錄</button> <button class="btn" @click="fun_record_update">更新記錄</button> <button class="btn" @click="fun_record_get">獲取記錄</button> <button class="btn" @click="fun_record_getall">獲取所有記錄</button> </div> <div class="infoBox"> <p class="pInfo" v-for="(item, i) in messages">{{ item }}</p> </div> </div> </template> <script> import IndexDBCache from "./utils/uIndexDB"; let dbCache = null; export default { data() { return { messages: [], }; }, //頁面加載時初始化 indexdb mounted() { debugger; dbCache = new IndexDBCache((msg) => this.supply_message(msg)); }, // //頁面銷毀時 關閉數據庫 // destroyed() { // debugger; // this.fun_db_close(); // }, methods: { fun_db_close() { dbCache.DB_Close(); }, //刪除數據庫 fun_db_remove() { dbCache.DB_Remove((msg) => this.supply_message(msg)); }, //寫入記錄 fun_record_create() { // let objParam = { // senceid: "111", // version: "V1", // path: "Http://xxxx.com", // value: "aaa", // }; let objParam = { senceid: "222", version: "V1", path: "Http://yyyy.com", value: "bbb", }; dbCache.Record_Add(objParam).then((msg) => { this.messages.push("寫入: " + msg); }); }, //刪除記錄 fun_record_remove() { dbCache.Record_Remove(2).then((msg) => { this.messages.push("刪除: " + msg); }); }, //更新記錄 fun_record_update() { let objParam = { id: 2, senceid: "222", version: "V2", path: "Http://yyyy-2.com", value: "bbb2", }; dbCache.Record_Update(objParam).then((msg) => { this.messages.push("更新: " + msg); }); }, //獲取數據 fun_record_get() { dbCache.Record_Get().then((msg) => { this.messages.push("讀取: " + JSON.stringify(msg)); }); }, //獲取所有數據 fun_record_getall() { dbCache.Record_GetAll().then((msg) => { this.messages.push("讀取: " + JSON.stringify(msg)); }); }, //創建表 fun_table_create() { this.messages.push( "請修改版本號更新數據庫,參考:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase" ); }, //刪除表 fun_table_remove() { this.messages.push( "在versionchange中實現 deleteObjectStore 方法 ,參考://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase" ); }, //更新表 fun_table_update() { this.messages.push( "請修改版本號更新數據庫,參考:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase" ); }, //獲取表 fun_table_get() { dbCache.Table_Get().then((msg) => { this.messages.push("獲取表: " + JSON.stringify(msg)); }); }, //輸出信息 supply_message(msg) { this.messages.push(msg); }, }, }; </script> <style scoped> .box { margin: 20px; } .btnBox { margin: 10px; } .btn { width: 100px; height: 30px; } .infoBox { min-height: 50px; border: 1px solid grey; margin: 10px; padding: 5px 10px; } .pInfo { margin: 5px; } </style>
3) src / utils / uIndexDB.js

const indexDB = window.indexedDB || window.webkitIndexedDB ||
window.mozIndexedDB;
class IndexDBCache {
//構造函數
constructor(callback) {
this._db = null; //數據庫
this._transaction = null; //事務
this._request = null;
this._dbName = 'cacheModel'; //數據庫名
this._cacheTableName = 'tabmodalcache'; //表名
this._dbversion = 1; //數據庫版本
this.DB_Init(callback); //初始化數據庫
}
//初始化數據庫
DB_Init(callback) {
this._request = indexDB.open(this._dbName, this._dbversion); //數據庫名,版本
this._request.onsuccess = event => {
this._db = this._request.result;
let msg = 'indexdb打開成功!'
console.log(msg);
if (typeof callback === 'function') callback(msg);
};
this._request.onerror = event => {
let msg = 'indexdb初始化失敗!'
console.log(msg);
if (typeof callback === 'function') callback(msg);
};
this._request.onupgradeneeded = event => {
let db = this._request.result;
if (!db.objectStoreNames.contains(this._cacheTableName)) {
let store = db.createObjectStore(this._cacheTableName, {
keyPath: 'id', //設置主鍵
autoIncrement: true //自動生成主鍵
});
//創建索引
store.createIndex("INDEX_ID", "id", {
unique: true
});
//創建索引
store.createIndex('index_senceid', 'senceid', {
unique: false, //true:唯一,false:可重復
});
}
let msg = 'indexdb升級成功!';
console.log(msg);
if (typeof callback === 'function') callback(msg);
}
}
//刪除數據庫
DB_Remove(callback) {
var DBDeleteRequest = indexedDB.deleteDatabase(this._dbName);
DBDeleteRequest.onerror = function (event) {
console.log('Error');
};
DBDeleteRequest.onsuccess = function (event) {
let msg = 'indexdb刪除成功!';
console.log(msg);
if (typeof callback === 'function') callback(msg);
};
}
//關閉數據庫
DB_Close() {
this._db.close();
}
//獲取表
Table_Get() {
return new Promise((resolve, reject) => {
resolve(this._db.objectStoreNames);
});
}
/** 新增數據
* obj: {path:'Http://xxxxx.com',version:'V1',value:'ccc'}
* */
Record_Add(obj) {
return new Promise((resolve, reject) => {
let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
let store = transaction.objectStore(this._cacheTableName);
let response = store.add(obj);
response.onsuccess = (cc, mm) => {
let msg = `新增數據${JSON.stringify(obj)}`
resolve(msg);
}
response.onerror = (event) => {
console.log('新增失敗');
reject(event);
}
})
}
//獲取數據
Record_Get() {
return new Promise((resolve, reject) => {
let transaction = this._db.transaction(this._cacheTableName);
var objectStore = transaction.objectStore(this._cacheTableName);
//主健讀取
// var request = objectStore.get(1);
//使用索引讀取
var index = objectStore.index('index_senceid');
var request = index.get('222');
request.onsuccess = () => {
resolve(request.result);
};
request.onerror = (event) => {
console.log('獲取失敗');
reject(event);
};
});
}
//獲取所有數據
Record_GetAll() {
return new Promise((resolve, reject) => {
let transaction = this._db.transaction(this._cacheTableName);
var objectStore = transaction.objectStore(this._cacheTableName);
let request = objectStore.getAll();
request.onsuccess = () => {
resolve(request.result);
};
request.onerror = (event) => {
console.log('獲取失敗');
reject(event);
};
})
}
/** 更新數據
* obj: {path:'Http://xxxxx.com',version:'V1',value:'fff'}
*/
Record_Update(obj) {
return new Promise((resolve, reject) => {
let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
let store = transaction.objectStore(this._cacheTableName);
var request = store.put(obj);
request.onsuccess = function (event) {
let msg = '數據更新成功';
console.log(msg);
resolve(msg);
};
request.onerror = function (event) {
console.log('數據更新失敗');
reject(event);
}
});
}
//刪除數據
Record_Remove(id) {
return new Promise((resolve, reject) => {
let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
let store = transaction.objectStore(this._cacheTableName);
let response = store.delete(id);
response.onsuccess = () => {
console.log('刪除成功');
resolve('刪除成功');
}
response.onerror = (event) => {
console.log('刪除失敗');
reject(event);
}
})
}
}
export default IndexDBCache;
4. 測試效果
引用:http://www.ruanyifeng.com/blog/2018/07/indexeddb.html
引用:https://www.jianshu.com/p/9df6989d07f5
引用:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase