indexDB在vue项目中的应用
ndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。虽然Web Storage在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。(1)Indexed DB:索引数据库,操作简便,目前主流浏览器正努力实现对index DB的支
ndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。虽然 Web Storage 在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。
(1)Indexed DB:
索引数据库,操作简便,目前主流浏览器正努力实现对index DB的支持。
Web SQL Database实际上已经被废弃,而HTML5的支持的本地存储实际上变成了Web Storage(Local Storage和Session Storage)与IndexedDB。Web Storage使用简单字符串键值对在本地存储数据,方便灵活,但是对于大量结构化数据存储力不从心,IndexedDB是为了能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。
(2)indexDB主要对象介绍:
• IDBFactory:打开数据库的工厂对象,用于打开数据库,并管理数据库版本。
• IDBOpenDBRequest:请求对象,对数据库的访问、操作都是基于请求的,通过请求对象获取其他DOM对象。
• IDBDatabase:数据库对象,封装了对数据库表的创建、编辑等功能。
• IDBObjectStore:类似于数据库的数据表。
• IDBIndex:数据库索引对象,用于创建数据表的索引。
• IDBTransaction:数据库事物控制对象。
• IDBCursor:数据库访问游标,用于访问数据。
(3)异步API
在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式,比如打开数据库的操作
var request=window.indexedDB.open('testDB');
这条指令并不会返回一个DB对象的句柄,我们得到的是一个IDBOpenDBRequest对象,而我们希望得到的DB对象在其result属性中,
这条指令请求的响应是一个 IDBDatabase对象,这就是IndexedDB对象,
除了result,IDBOpenDBRequest接口定义了几个重要属性
• onerror: 请求失败的回调函数句柄
• onsuccess:请求成功的回调函数句柄
• onupgradeneeded:请求数据库版本变化句柄
所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。
开始使用
新建indexDb.js,封装增删改
import Vue from 'vue';
let local = {
save(key, value) {
if (typeof value === 'string') {
localStorage.setItem(key, value);
} else {
localStorage.setItem(key, JSON.stringify(value));
}
},
fetch(key) {
return JSON.parse(localStorage.getItem(key)) || {}
},
del(key) {
if (key) {
localStorage.removeItem(key);
} else {
localStorage.clear();
}
}
}
// 用来获取和设置 删除 indexDB 存储
let myDB = {
name: "yancao",
version: 0,
db: null,
ojstore: [{
name: "goods", //商品表
keyObj: {
keyPath: "goods_id",
autoIncrement: true
}, //自增主键
creatIndex: [{
keyname: 'goods_isn',
keyPath: 'goods_isn',
unique: true
}, {
keyname: 'bitcode',
keyPath: 'bitcode',
unique: true
}, {
keyname: 'is_tobacco',
keyPath: 'is_tobacco',
}, {
keyname: 'is_active',
keyPath: 'is_active'
},
{
keyname: 'keywords', //关键字搜索
keyPath: ['goods_isn', 'goods_name', 'shortalpha']
},
]
},
{
name: "canOrderInfo", //可定量商品信息表
keyObj: {
keyPath: "category_code",
autoIncrement: false
}, //自增主键
creatIndex: [
{
keyname: 'can_order_index',
keyPath: 'can_order_index',
unique: true
}
]
},
{
name: "goodscategory_info", //类别表
keyObj: {
keyPath: "category_code",
autoIncrement: false
}, //自增主键
creatIndex: [{
keyname: 'category_code',
keyPath: 'category_code',
unique: true
},
{
keyname: 'category_name',
keyPath: 'category_name',
unique: true
}, {
keyname: 'order_index',
keyPath: 'order_index',
unique: true
}
]
},
{
name: "stores", //类别表
keyObj: {
keyPath: "store_id",
autoIncrement: true
}, //自增主键
creatIndex: [{
keyname: 'goods_isn',
keyPath: 'goods_isn',
unique: true
},
{
keyname: 'unit_uuid',
keyPath: 'unit_uuid'
}, {
keyname: 'quantity',
keyPath: 'quantity'
}
]
},
{
name: "orders", //订单表
keyObj: {
keyPath: "id",
autoIncrement: true
}, //自增主键
creatIndex: [{
keyname: 'order_id',
keyPath: 'order_id',
unique: true
},{
keyname: 'pay_type', //支付类型
keyPath: 'pay_type'
}, {
keyname: 'state',
keyPath: 'state', //订单支付状态 0 未支付(待支付) 1 已支付 2 支付异常 3 订单关闭
},
{
keyname: 'upstate',
keyPath: 'upstate', //订单状态 是否已上送 0 未上送 1 已上送
},
{
keyname: 'searchKey',
keyPath: ['upstate', 'state'], //根据订单状态和支付状态建立索引
},
{
keyname: 'fund_channel', //支付通道
keyPath: 'fund_channel',
}
]
}
]
};
let indexDB = {
indexedDB: window.indexedDB || window.webkitindexedDB,
IDBKeyRange: window.IDBKeyRange || window.webkitIDBKeyRange, //键范围
openDB: function(myDB, callback) {
//建立或打开数据库,建立对象存储空间(ObjectStore)
var self = this;
var version = myDB.version || 1;
var request = self.indexedDB.open(myDB.name, version);
request.onerror = function(e) {
};
request.onsuccess = function(e) {
myDB.db = e.target.result;
callback(e.target.result);
};
request.onupgradeneeded = function(e) {
var db = e.target.result,
transaction = e.target.transaction,
store;
myDB.ojstore.forEach(function(storeObj) {
if (!db.objectStoreNames.contains(storeObj.name)) {
//没有该对象空间时创建该对象空间
store = db.createObjectStore(storeObj.name, storeObj.keyObj);
if (storeObj.creatIndex.length > 0) { //如果有多个索引
storeObj.creatIndex.forEach(function(item) {
if (item.unique) {
store.createIndex(item.keyname, item.keyPath, {
unique: item.unique
});
} else {
store.createIndex(item.keyname, item.keyPath,{
unique: false
});
}
})
}
}
})
}
},
deletedb: function(dbname, callback) {
//删除数据库
var deleteQuest = this.indexedDB.deleteDatabase(dbname);
deleteQuest.onerror = function(result) {
console.log('删除数据库出错');
callback(result);
};
deleteQuest.onsuccess = function(result) {
console.log(dbname + '数据库已删除')
if (callback && (typeof callback === 'function')) {
callback(result);
}
}
},
closeDB: function(db) {
//关闭数据库
db.close();
console.log('数据库已关闭')
},
addData: function(db, storename, data, callback) {
//添加数据,重复添加会报错
var self = this;
var store = db.transaction(storename, 'readwrite').objectStore(storename),
request;
let addTime = new Date()+'';
if (data.length) {
for (var i = 0; i < data.length; i++) {
data[i].addTime = addTime;
let modData = data[i];
request = store.add(modData);
request.onerror = function(err) {
err.respcode='0001';
callback(err);
self.putData(db, storename, modData);
};
request.onsuccess = function(resp) {
resp.respcode='0000';
callback(resp);
};
}
}
},
//根据key修改更新时间
updateDataByKey: function(db, storeName, value, QTY, addtime) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(value);
return new Promise((resolve, reject) => {
request.onsuccess = function(e) {
var stocktable = e.target.result;
if (stocktable) {
stocktable.qty = QTY;
stocktable.addtime = addtime;
resolve(store.put(stocktable));
} else {
reject(false);
}
};
})
},
//根据key修改数量
updateDataByKeys: function(db, storeName, value, addtime, callback) {
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(value);
return new Promise((resolve, reject) => {
//console.log(addtime)
request.onsuccess = function(e) {
var stocktable = e.target.result;
if (stocktable) {
stocktable.qty += 1;
stocktable.addtime = addtime;
resolve(store.put(stocktable));
} else {
reject(false);
}
};
})
},
//通过游标遍历数据
getdatabycursor: function(db, storename) {
var objectStore = db.transaction(storename).objectStore(storename);
var dataList = [];
var i = 0;
return new Promise((resolve, reject) => {
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
dataList.push(cursor.value)
cursor.continue();
} else {
resolve(dataList);
}
};
})
},
getGoodsByMatchCursor: function(db,storename,str) { //根据游标 模糊查询goods
var objectStore = db.transaction(storename).objectStore(storename);
var dataList = [];
var i = 0;
return new Promise((resolve, reject) => {
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor){
if(cursor.value.bitcode.indexOf(str)!= -1||cursor.value.goods_name.indexOf(str)!= -1||cursor.value.shortalpha.indexOf(str)!= -1){
dataList.push(cursor.value);
}
cursor.continue();
} else {
resolve(dataList);
}
};
})
},
//根据key查询数量是否存在
getqtyBykey: function(db, storeName, key) {
var transaction = db.transaction(storeName);
var objectStore = transaction.objectStore(storeName);
var request = objectStore.get(key);
request.onerror = function(event) {
console.log('事务失败');
};
return new Promise((resolve, reject) => {
request.onsuccess = function(event) {
if (request.result) {
//console.log(request.result.qty)
resolve(request.result);
} else {
resolve(false);
}
};
})
},
//根据游标索引值类型查找数据
getCusorBykey: function(db, storeName, searchkey, value1, searchtype, value2, callback) {
var transaction = db.transaction(storeName);
var objectStore = transaction.objectStore(storeName);
var index = objectStore.index(searchkey);
if (value1) {
// 仅匹配 value
var KeyRange;
switch (searchtype) {
case 'lowerBound': 匹配所有超过value的,但不包括value
KeyRange = IDBKeyRange.lowerBound(value, true);
break;
case 'upperBound': 匹配所有不超过value的,但不包括value
KeyRange = IDBKeyRange.upperBound(value, true);
break;
case 'boundTrue': //匹配所有在value1和value2之间的,但不包括value1和value2
KeyRange = IDBKeyRange.bound(value1, value2, true, true);
break;
case 'boundFalse': //匹配所有在value1和value2之间的,但包括value1和value2
KeyRange = IDBKeyRange.bound(value1, value2, false, false);
break;
default:
KeyRange = IDBKeyRange.only(value1);
}
var data = [];
index.openCursor(KeyRange).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// cursor.key 是一个 name, 就像 "Bill", 然后 cursor.value 是整个对象。
data.push(cursor.value);
cursor.continue();
} else {
callback(data);
}
};
}
},
// 通过索引获取数据
read: function(db, storeName, searchIndex, indexValue) {
var transaction = db.transaction(storeName);
var objectStore = transaction.objectStore(storeName);
var indexs = objectStore.index(searchIndex);
// 根据索引searchIndex找到紧仅匹配 值为indexValue的数据
var request = indexs.openCursor(IDBKeyRange.only(indexValue));
// var request=indexs.get(indexValue);
return new Promise((resolve, reject) => {
request.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
resolve(cursor);
} else {
resolve(false);
}
}
})
},
//更新单条数据
putData: function(db, storename, data, callback) {
//添加数据,重复添加会更新原有数据
let updatetime = new Date() + '';
if (data) {
var modData = data;
modData.updatetime = updatetime;
var store = db.transaction(storename, 'readwrite').objectStore(storename),
request = store.put(modData);
request.onerror = function(err) {
console.log('put err',err);
};
request.onsuccess = function() {
};
}
},
//更新多条数据
putDatas: function(db, storename, data, callback) {
//添加数据,重复添加会更新原有数据
let updatetime = new Date();
let _this = this;
根据游标取出所有数据
this.getdatabycursor(db, storename).then(arr => {
if (arr.length == 0) { //数据库为空
console.log("全部添加")
var store = db.transaction(storename, 'readwrite').objectStore(storename),
request;
for (var i = 0, len = dataArr.length; i < len; i++) {
request = store.add(dataArr[i]);
request.onerror = function() {
};
request.onsuccess = function(result) {
if (callback && (typeof callback === 'function')) {
callback(result);
}
};
}
} else { //数据库中有数据
for (var i = 0, len = data.length; i < len; i++) {
//查找是否有相同数据,有更新,无添加
this.read(db, storename, 'id', data[i].id).then(x => {
if (x) {
_this.putData(db, storename, data[i]);
} else {
console.log("再次添加")
_this.addData(db, storename, data[i]);
}
})
}
}
})
},
getAllData(db, storename, callback) {
//获取所有数据
var store = db.transaction(storename, 'readwrite').objectStore(storename);
var allRecords = store.getAll();
allRecords.onsuccess = function() {
if (typeof(callback) === 'function') {
callback(allRecords.result);
}
};
},
//根据key查找到数据
getDataByKey: function(db, storename, key, callback) {
//根据存储空间的键找到对应数据
var store = db.transaction(storename, 'readwrite').objectStore(storename);
var request = store.get(key);
request.onerror = function() {
console.log('getDataByKey error');
};
request.onsuccess = function(e) {
var result = e.target.result;
console.log('查找数据成功', result)
if (typeof(callback) === 'function') {
callback(result);
}
};
},
deleteData: function(db, storename, key) {
//删除某一条记录
var store = store = db.transaction(storename, 'readwrite').objectStore(storename);
store.delete(key);
console.log('已删除存储空间' + storename + '中' + key + '记录');
},
clearData: function(db, storename) {
var self = this;
var version = myDB.version || 1;
const request = self.indexedDB.open(db, version);
request.addEventListener('success', e => {
var sdb=e.target.result;
console.log('db',sdb);
var store = sdb.transaction(storename, 'readwrite').objectStore(storename);
store.clear();
});
}
}
export default {
install: function(Vue) {
Vue.prototype.$local = local;
Vue.prototype.$myDB = myDB;
Vue.prototype.$indexDB = indexDB;
}
}
//其他应用
//****************添加数据****************************;
// this.$indexDB.addData(myDB.db, myDB.ojstore.name, cartData);
// ****************获取所有数据****************************;
// this.$indexDB.getAllData(myDB.db, myDB.ojstore.name);
//*******************put重复添加*************************;
// this.$indexDB.putData(myDB.db,myDB.ojstore.name,cartData);
//*******************获取指定数据*************************";
// this.$indexDB.getDataByKey(
// myDB.db,
// myDB.ojstore.name,
// cartData[0].id
// );
//******************删除数据1001************;
// this.$indexDB.deleteData(myDB.db,myDB.ojstore.name,1001);
//******************删除全部数据************;
// this.$indexDB.clearData(myDB.db,myDB.ojstore.name);
//******************关闭数据库************;
// this.$indexDB.closeDB(myDB.db);
全局封装调用global.vue
const IndexDbControl = {
insertLocalData: function(indexDb, myDb, params) {
//插入数据到本地
let myDB = myDb;
indexDb.openDB(myDB, function(result) {
let localGoods = params.item_list;
let storename = params.table;
indexDb.addData(myDB.db, storename, localGoods, function(data) {
console.log('添加结果!', data);
});
});
},
searchLocalGoodsByKeyWords:function(indexDb, myDb,storename,keywords,callback){
indexDb.openDB(myDb, function(result) {
indexDb.getGoodsByMatchCursor(myDb.db, storename,keywords).then(data => {
console.log('search data', data);
let respData={};
if (data) {
respData.respcode="0000";
respData.datas=data;
} else {
respData.respcode="0001";
}
callback(respData);
});
});
},
searchLocalDataByParams: function(indexDb, myDb, params,callback) {
//根据搜索条件查询
let myDB = myDb;
let returnData={};
indexDb.openDB(myDB, function(result) {
let storename = params.table;
if (params.queryIndex) {
indexDb.read(myDB.db, storename, params.queryIndex, params.query).then(data => {
console.log('x data', data);
let respData={};
if (data.value) {
respData.respcode="0000";
respData.value=data.value;
} else {
respData.respcode="0001";
}
callback(respData);
});
} else {
console.log('查询本地数据库 storename',storename);
indexDb.getAllData(myDB.db, storename, function(data) {
console.log('查询出的数据!', data);
callback(data);
});
}
});
}
};
export default {
IndexDbControl
}
项目成功运行后
浏览器调试中
indexDb下会生成对应的表和接口返回的数据
更多推荐
所有评论(0)