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();
  }
};
相关推荐
Danta28 分钟前
百度网盘一面值得look:我有点难受🤧🤧
前端·javascript·面试
OpenTiny社区39 分钟前
TinyVue v3.22.0 正式发布:深色模式上线!集成 UnoCSS 图标库!TypeScript 类型支持全面升级!
前端·vue.js·开源
dwqqw1 小时前
opencv图像库编程
前端·webpack·node.js
Captaincc2 小时前
为什么MCP火爆技术圈,普通用户却感觉不到?
前端·ai编程
LUCIAZZZ2 小时前
说一下Redis的发布订阅模型和PipeLine
java·数据库·redis·缓存·操作系统
工业互联网专业2 小时前
基于JavaWeb的花店销售系统设计与实现
java·vue.js·spring boot·毕业设计·源码·课程设计·花店销售系统
阿虎儿2 小时前
MCP
前端
毕小宝2 小时前
编写一个网页版的音频播放器,AI 加持,So easy!
前端·javascript
万水千山走遍TML2 小时前
JavaScript性能优化
开发语言·前端·javascript·性能优化·js·js性能
Aphasia3112 小时前
react必备JS知识点(一)——判断this指向👆🏻
前端·javascript·react.js