VUE - IndexDB浏览器数据库做缓存
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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