indexDB在vue项目中的应用

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下会生成对应的表和接口返回的数据

 

 

 

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值