vue使用indexedDB缓存教程

1.前端缓存几种方式: cookie、localStorage、sessionStorage、indexedDB,下面详细介绍indexedDB

2.完整代码

class DBManager {
  dbName: any = null;
  version: any = null;
  db: any = null;

  /**
   * 初始化数据库名、版本
   * @param dbName
   * @param version
   */
  constructor(dbName: String, version: String | Number) {
    this.dbName = dbName;
    this.version = version;
    this.db = null;
  }

  /**
   * 打开数据库
   * @param callback
   * @returns
   */
  openDB(storeName?: String, keyPath?: String, keys?: Array<any>) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        resolve(this.db);
      } else {
        const cmd = indexedDB.open(this.dbName, this.version);
        cmd.onsuccess = (e: any) => {
          this.db = e.target.result;
          resolve(this.db);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
        cmd.onupgradeneeded = (e: any) => {
          this.createStore(storeName, keyPath, keys);
        };
      }
    });
  }

  /**
   * 关闭数据库
   */
  closeDB() {
    if (this.db) {
      this.db.close();
      this.db = null;
    }
  }

  /**
   * 删除数据库
   * @returns
   */
  deleteDB() {
    return new Promise((resolve, reject) => {
      const cmd = indexedDB.deleteDatabase(this.dbName);
      cmd.onsuccess = (e: any) => {
        resolve("");
      };
      cmd.onerror = (e: any) => {
        reject(e.target.error);
      };
    });
  }

  /**
   * 创建对象仓库
   * @param storeName
   * @param keyPath
   * @param keys
   * @returns
   */
  createStore(storeName?: String, keyPath?: String, keys?: Array<any>) {
    return new Promise(async (resolve, reject) => {
      if (this.db) {
        const store = this.db.createObjectStore(storeName, {
          keyPath: keyPath,
          autoIncrement: true,
        });
        if (keys) {
          keys.forEach((key: any) => {
            store.createIndex(key, key, { unique: key === keyPath ? true : false });
          });
        }
        resolve(this.db);
      } else {
        reject("数据库未打开createStore");
      }
    });
  }

  /**
   * 增加数据
   * @param storeName
   * @param data
   * @returns
   */
  insert(storeName: String, data: any) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readwrite");
        const store = transaction.objectStore(storeName);
        const cmd = store.add(data);
        cmd.onsuccess = (e: any) => {
          resolve(e.target.result);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 查询数据,默认根据主键查询
   * @param storeName
   * @param value
   * @returns
   */
  queryByKey(storeName: String, value: any) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readonly");
        const store = transaction.objectStore(storeName);
        const cmd = store.get(value);
        cmd.onsuccess = (e: any) => {
          resolve(e.target.result);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 查询全部数据记录
   * @param storeName
   * @returns
   */
  queryAll(storeName: String) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readonly");
        const store = transaction.objectStore(storeName);
        const cmd = store.getAll();
        cmd.onsuccess = (e: any) => {
          resolve(e.target.result);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 通过游标查询,跟queryByIndex的区别是:游标查询可定义查询条件,比如年龄在18-24之间的数据
   * @param storeName
   * @param range 查询条件
   * @param direction 排序顺序
   * @returns
   */
  queryByCursor(storeName: String, key?: String, range?: any, direction: String = "next") {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readonly");
        const store = transaction.objectStore(storeName);
        const index = key ? store.index(key) : "";
        const cursor = range ? index.openCursor(range, direction) : store.openCursor();
        const result: Array<any> = [];
        cursor.onsuccess = (e: any) => {
          const cursor = e.target.result;
          if (cursor) {
            result.push(cursor.value);
            cursor.continue();
          }
          resolve(result);
        };
        cursor.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 通过键值对查询
   * @param storeName
   * @param indexName
   * @param value
   * @returns 获取:键为indexName,值为value 的那条数据
   */
  queryByIndex(storeName: String, indexName: String, value: any) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readonly");
        const store = transaction.objectStore(storeName);
        const cmd = store.index(indexName).get(value);
        cmd.onsuccess = (e: any) => {
          resolve(e.target.result);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 更新数据
   * @param storeName
   * @param key
   * @param data
   * @returns
   */
  update(storeName: String, key: String, newData: any) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readwrite");
        const store = transaction.objectStore(storeName);
        const cmd = store.get(key);
        cmd.onsuccess = (e: any) => {
          let data = e.target.result;
          Object.assign(data, newData);
          const requestUpdate = store.put(data);
          requestUpdate.onsuccess = (e: any) => {
            resolve(e.target.result);
          };
          requestUpdate.onerror = (e: any) => {
            reject(e.target.error);
          };
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }

  /**
   * 删除数据
   * @param storeName
   * @param key
   * @returns
   */
  delete(storeName: String, key: String) {
    return new Promise((resolve, reject) => {
      if (this.db) {
        const transaction = this.db.transaction(storeName, "readwrite");
        const store = transaction.objectStore(storeName);
        const cmd = store.delete(key);
        cmd.onsuccess = (e: any) => {
          resolve(e.target.result);
        };
        cmd.onerror = (e: any) => {
          reject(e.target.error);
        };
      } else {
        reject("数据库未打开");
      }
    });
  }
}
export default DBManager;

3.在项目中使用

template:
    <button @click="learnDb('open')">打开</button>
    <button @click="learnDb('add')">添加</button>
    <button @click="learnDb('search')">查询</button>
    <button @click="learnDb('delete')">删除</button>
    <button @click="learnDb('update')">更新</button>
    <button @click="learnDb('close')">关闭</button>
    <button @click="learnDb('clearn')">清除</button>


script:
    //学习indexedDB
let myDB = new DBManager("zhengjie", 1);
let learnDb = async (type: String) => {
  if (type == "clearn") {
    myDB.deleteDB();
  } else if (type == "open") {
    myDB.openDB("users", "name", ["name", "age"]);
  } else if (type == "add") {
    myDB.insert("users", { name: "整洁", age: 18 });
  } else if (type == "search") {
    // let a = await myDB.queryByKey("users", "整洁");
    // let a = await myDB.queryAll("users");
    // const range = IDBKeyRange.only(24);
    // let a = await myDB.queryByCursor("users", "age", range); //查询名字(name)为整洁的数据
    let a = await myDB.queryByIndex("users", "age", 24);
    console.log("查找数据", a);
  } else if (type == "delete") {
    myDB.delete("users", "整洁");
  } else if (type == "update") {
    myDB.update("users", "整洁", { name: "整洁", age: 24 });
  } else if (type == "close") {
    myDB.closeDB();
  }
};
相关推荐
ZJ_.11 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营15 分钟前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood41 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端43 分钟前
0基础学前端-----CSS DAY9
前端·css
joan_851 小时前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
m0_748236111 小时前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_748248942 小时前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_748235612 小时前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O4 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js