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)