vue-indexDB 浏览器数据库操作类
375
2023-6-16
/**
 * 这是前端浏览器indexDB工具类
 * 可实现创建数据库增删改查操作
 * date 20220626 author by lin
 */

export class dbActive {
  /**
   * 构造函数
   * @param dbname type string 数据库名称
   * @param tbName type []表对象名称多个表数组
   * @param field  type obj表字段对象,直接传入新增数据的对象如{height:15},那么将height作为字段名
   */

  constructor(dbname, tbName, field) {
    this.db = null; //数据库对象
    this.tableName = tbName; //表格名称[]
    this.dbName = dbname //数据库名称 myDB
    this.dataList = [];
    this.field = field;
    this.result = { success: true, msg: "操作成功", data: [] }  //默认返回样式

  }

  /**
   * 由于初始化数据库是异步函数,此时需用await等待其执行完毕,先调用此函数
   * @param v 版本号默认为1,
   * @returns {Promise<unknown>}
   */
  async initDB(v) {
    v = v > 1 ? v : 1
    return new Promise(resolve => {

      let request = indexedDB.open(this.dbName, v);

      // error 回调
      request.onerror = event => {
        console.log('数据库打开/创建报错', event)
        //如果是版本引起错误,提取当前版本
        if (event.target.error.message.indexOf('requested version')) {
          let versionArray = event.target.error.message.match(/\d+(.\d+)?/g) //提取错误信息,将当前版本号提取出来
          resolve(this.initDB(versionArray[1]))
          //alert(event.target.error.message)
        }
        else {
          this.result.msg = event.target.error.message
          this.result.success = false
          resolve(this.result)
        }

      }

      //如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded。
      //升级后自动触发success
      request.onupgradeneeded = event => {
        this.db = event.target.result;

        //建表 名为person,主键为id
        this.tableName.map((item) => {
          if (this.db.objectStoreNames.contains(item)) { // 判断表是否存在
            this.db.deleteObjectStore(item);
          }
          //主键自增ID
          let store = this.db.createObjectStore(item, {
            keyPath: 'id', autoIncrement: true
          });
          for (let key in this.field) {
            // arrayColors.push(key);
            //新建索引名称、索引所在的属性、配置对象(说明该属性是否允许有重复的值)

            store.createIndex(key, key, {
              unique: false
            });
          }

        })

        console.log('数据库升级')
      }

      // success
      request.onsuccess = event => {
        this.db = event.target.result;
        // if (!this.db.objectStoreNames.contains(this.tableName)) { // 判断表是否存在
        //   //建表 名为person,主键为id
        //   this.tableName.map((item)=>{
        //     //主键自增ID
        //     let store = this.db.createObjectStore(item, {
        //       keyPath: 'id',autoIncrement: true
        //     });
        //     for (let key in this.field) {
        //       // arrayColors.push(key);
        //       //新建索引名称、索引所在的属性、配置对象(说明该属性是否允许有重复的值)
        //
        //       store.createIndex(key, key, {
        //         unique: false
        //       });
        //     }
        //   })
        //
        // }

        console.log('数据库打开/创建成功', event)
        this.db.onversiοnchange = e => {
          this.db.close() // 关闭连接
          console.log("页面内容已过期,请刷新");

        }
        resolve(this.getList());
      }

    });
  }

  /**
   * 删除数据库
   * @param dbName
   * @returns {Promise<unknown>}
   */

  databaseDel(dbName) {
    return new Promise((resolve => {
      let request = indexedDB.open(dbName);
      request.onerror = ev => {
        resolve({ msg: '数据库打开失败,无法删库', success: false })
      }
      request.onsuccess = ev => {
        window.indexedDB.deleteDatabase(dbName)
        resolve({ msg: '删除数据库成功', success: true })
      }
    }))
  }

  /**
   * 新增
   * @param table 目标表格
   * @param person 数据
   * @returns {Promise<void>}
   */

  async clickAdd(table, person) {
    let tbName = table
    if (!tbName) {
      tbName = this.tableName[0]
    }
    return new Promise(resolve => {
      // 建立读写事务,向对象仓库写入数据记录

      // person.id =  new Date().getTime()
      let request = this.db.transaction([tbName], 'readwrite').objectStore(tbName).add(person)
      request.onsuccess = event => {
        console.log(event.target.result)
        this.result.success = true
        this.result.msg = '新增成功'
        this.result.lastid = event.target.result
        resolve(this.result)

      };
      request.onerror = event => {
        this.result.msg = "重复数据写入失败"
        this.result.success = false
        resolve(this.result)
      }
    })

    // return this.dataList;
  }
  /**
   * 关键词模糊查询特定表数据
   * @param table
   * @param keyword
   * @returns {Promise<unknown>}
   */
  fuzzySearch(table, keyword) {
    return new Promise((resolve) => {
      let tbName = table
      if (!tbName) {
        tbName = this.tableName[0]
      }
      let list = [];
      const store = this.db.transaction([tbName]).objectStore(tbName)
      const request = store.getAll()
      request.onsuccess = (e) => {
        // console.log(e.target.result);
        if (!keyword) {
          list = e.target.result

        }
        else {
          let data = e.target.result

          data.forEach((item) => {

            let value = Object.values(item).join(";");
            if (!!~value.toUpperCase().indexOf(keyword.toUpperCase())) {

              list.push(data)
            }
          })
        }
        this.result.success = true
        this.result.data = list
        resolve(this.result)
      }
      request.onerror = () => {
        console.log('查询失败');
        this.result.success = false
        reject(this.result)
      }
    })

  }

  /**
   * 索引查询数据
   * @param table  名称
   * @param param 参数
   * @param filed 查找的字段
   * @returns {Promise<unknown>}
   */
  async read(table, param, filed) {
    let tbName = table
    if (!tbName) {
      tbName = this.tableName[0]
    }

    return new Promise((resolve => {
      let transaction = this.db.transaction([tbName]);
      let objectStore = transaction.objectStore(tbName);
      let request = null
      if (!filed)
        request = objectStore.get(param);
      else {
        //通过索引获取数据
        request = this.db.transaction([tbName], 'readonly').objectStore(tbName).index(filed).get(param);

      }
      request.onerror = function (event) {
        console.log('获取列表失败');
        this.result.msg = '获取列表失败'
        this.result.success = false

        resolve(this.result)
      };

      request.onsuccess = function (event) {
        this.result.success = true
        if (request.result) {
          this.result.data = request.result
          resolve(this.result)
        } else {
          console.log('未获得数据记录');
          this.result.msg = "查为空"
          resolve(this.result)
        }
      };
    }))
  }

  /**
   * 获取表所有数据
   * @param   table 获取的目标对象仓库如果没有,则默认tablename[0]
   * @returns {*[]}
   */
  async getList(table) {
    return new Promise((resolve, reject) => {
      let tbName = table
      if (!tbName) {
        tbName = this.tableName[0]
      }
      const store = this.db.transaction([tbName]).objectStore(tbName)
      const request = store.getAll()
      request.onsuccess = (e) => {
        this.result.success = true
        // console.log(e.target.result);
        this.result.data = e.target.result
        resolve(this.result)
      }
      request.onerror = () => {
        console.log('查询失败');
        this.result.success = false
        resolve(this.result)
      }
    })
  }

  /**
   * 批量更新数据
   * @param table 目标表格对象
   * @param data  数据值[]
   */
  update(table, data) {
    let tbName = table
    if (!tbName) {
      tbName = this.tableName[0]
    }
    let msg = ''
    return new Promise(resolve => {
      if (data.constructor == Object) {
        let request = this.db.transaction([tbName], 'readwrite').objectStore(tbName).put(data)
        request.onsuccess = event => {
          console.log('数据更新成功')
          msg += '更新成功'
        }
        request.onerror = event => {

          console.log('数据更新失败')
          msg += '更新失败'
        }
      }
      else if (data.constructor == Array) {
        data.map((item) => {
          let request = this.db.transaction([tbName], 'readwrite').objectStore(tbName).put(item)
          request.onsuccess = event => {
            console.log('更新成功')
            msg += '更新成功'
          }
          request.onerror = event => {

            console.log('更新失败')
            msg += '更新失败'
          }
        })
      }
      this.result.msg = msg
      this.result.success = true
      resolve(this.result)
    })
  }


  /**
   * 删除
   * @param table 目标表格
   * @param id    主键ID
   * @returns {Promise<unknown>}
   */
  clickDel(table, id) {
    let tbName = table
    if (!tbName) {
      tbName = this.tableName[0]
    }
    return new Promise(resolve => {
      if (id.constructor == Array) {
        id.map((item) => {
          let request = this.db.transaction([tbName], 'readwrite')
            .objectStore(tbName)
            .delete(item);
          request.onsuccess = event => {
            this.notify('删除成功')
          };

          request.onerror = event => {
            this.notify('删除失败')
          }
        })
        resolve(this.getList(tbName))
      }
      else {
        let request = this.db.transaction([tbName], 'readwrite')
          .objectStore(tbName)
          .delete(id);

        request.onsuccess = event => {
          this.notify('删除成功')
          resolve(this.getList(tbName))
        };

        request.onerror = event => {
          this.notify('删除失败')
          this.result.success = false
          this.result.msg = '删除失败'
          resolve(this.result)
        }
      }
    })
  }
  notify = (msg) => {
    console.log(msg)
  }
}

转自: https://blog.csdn.net/weixin_45214986/article/details/126405928