环境

  • Windows 10
  • Node.js v18.0.0
  • Yarn (用npmpnpm也没问题)
  • VS Code
  • Chrome

前言

  • 本教程间接给出办法,复制即可用。须要肯定的indexedDB的基础知识
  • 办法中并没有应用异步,依据须要自行添加即可
  • 尽管本教程给只出了VueReact两个JS框架的例子,然而其中函数也能够间接用于原生TS和JS

装置第三方库

  • file-saver:导出文件用,@types/file-saver是他的类型库
  • dayjs:工夫库,能够依据集体爱好抉择其余工夫库
yarn add -D file-saver @types/file-saver dayjs

Vue.js版本

App.vue

<script setup lang="ts">// 导入第三方库import dayjs from "dayjs";import { saveAs } from "file-saver";// 定义常量const dataBaseVer: number = 1; // 版本const dataBaseName: string = "MyIndexedDB"; // db名const dataBaseStore: string = "MyStore"; // store名const dataBaseKeyPath: string = "key"; // 主keyconst dataBaseLimit: number = 10000; // 数据条数限度const filename: string = `log_${dayjs().format("YYYYMMDD")}.txt`; // 导出的log文件名// 创立indexedDBconst createIndexedDB = (): void => {  const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName, dataBaseVer);  // 第一次执行,因为没有版本,所以会触发onupgradeneeded事件,此时新建store并追加主key  indexed.onupgradeneeded = (event: IDBVersionChangeEvent): void => {    const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;    if (!db.objectStoreNames.contains(dataBaseStore)) {      db.createObjectStore(dataBaseStore, {        keyPath: dataBaseKeyPath,      });    }  };  // 创立失败  indexed.onerror = (): void => {    console.log("Indexed Start Error");  };};// 增加logconst addLog = (log: string): void => {  // 获取log工夫戳  const time = dayjs().format("YYYY-MM-DD-HH:mm:ss:SSS");  const random = Math.ceil(Math.random() * 999);  const timeStamp = time + "_" + random + "Z";  // 关上db  const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName);  indexed.onsuccess = (event: Event): void => {    const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;    const trans: IDBTransaction = db.transaction(dataBaseStore, "readwrite");    const store: IDBObjectStore = trans.objectStore(dataBaseStore);    const count: IDBRequest<number> = store.count();    // 计算记录的数量,增加前先查看是否超过限度    count.onsuccess = (): void => {      // 没超过就增加      if (Number(count.result) <= dataBaseLimit) {        //以主键log为key,把工夫戳和log作为value,插入数据库        store.put({ [dataBaseKeyPath]: `[${timeStamp}] : ${log}` });        return;      } else {        // 没超过就删除最老的一条        store.openCursor().onsuccess = (event: Event): void => {          const cursor: any = (event.target as IDBRequest).result;          if (cursor) {            cursor.delete();          }        };      }    };    // 计算记录的数量失败    count.onerror = (): void => {      console.log("Count Error");    };  };  // db关上失败  indexed.onerror = (): void => {    console.log("Indexed Open Error");  };};// 读取logconst readDBandExport = (): void => {  let tmp: string[] = [];  // 关上db  const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName);  indexed.onsuccess = (event: Event): void => {    const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;    const trans: IDBTransaction = db.transaction(dataBaseStore, "readonly");    const store: IDBObjectStore = trans.objectStore(dataBaseStore);    // 遍历数据    store.openCursor().onsuccess = (event: Event): void => {      const cursor: any = (event.target as IDBRequest).result;      // 如果遍历项有数据就放入tmp,而后持续      if (cursor) {        tmp.push(cursor.key);        tmp.push("\r\n");        cursor.continue();      } else {        // 如果遍历项没有数据,阐明遍历完结,这时新建blob对象        const blob: Blob = new Blob(tmp, {          type: "text/plain;charset=utf-8",        });        // 导出文件        saveAs(blob, filename);      }    };    // 遍历数据失败    store.openCursor().onerror = (): void => {      console.log("OpenCursor Error");    };  };  // db关上失败  indexed.onerror = (): void => {    console.log("Indexed Open Error");  };};// 删除数据库const deleteIndexedDB = (): void => {  const indexed: IDBOpenDBRequest = indexedDB.deleteDatabase(dataBaseName);  // 删除胜利  indexed.onsuccess = (): void => {    console.log("Delete Success");  };  // 删除失败  indexed.onerror = (): void => {    console.log("Delete Error");  };};// 调用createIndexedDB();// 测试addLog("テスト");</script><template>  <main>    <h1>Vue.js</h1>    <button @click="addLog('ボタンからのテスト')">addLog</button>    <button @click="readDBandExport">readDBandExport</button>    <button @click="deleteIndexedDB">deleteIndexedDB</button>  </main></template>

React.js版本

App.tsx

// 导入第三方库import dayjs from "dayjs";import { saveAs } from "file-saver";function App() {  // 定义常量  const dataBaseVer: number = 1; // 版本  const dataBaseName: string = "MyIndexedDB"; // db名  const dataBaseStore: string = "MyStore"; // store名  const dataBaseKeyPath: string = "key"; // 主key  const dataBaseLimit: number = 10000; // 数据条数限度  const filename: string = `log_${dayjs().format("YYYYMMDD")}.txt`; // 导出的log文件名  // 创立indexedDB  const createIndexedDB = (): void => {    const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName, dataBaseVer);    // 第一次执行,因为没有版本,所以会触发onupgradeneeded事件,此时新建store并追加主key    indexed.onupgradeneeded = (event: IDBVersionChangeEvent): void => {      const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;      if (!db.objectStoreNames.contains(dataBaseStore)) {        db.createObjectStore(dataBaseStore, {          keyPath: dataBaseKeyPath,        });      }    };    // 创立失败    indexed.onerror = (): void => {      console.log("Indexed Start Error");    };  };  // 增加log  const addLog = (log: string): void => {    // 获取log工夫戳    const time = dayjs().format("YYYY-MM-DD-HH:mm:ss:SSS");    const random = Math.ceil(Math.random() * 999);    const timeStamp = time + "_" + random + "Z";    // 关上db    const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName);    indexed.onsuccess = (event: Event): void => {      const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;      const trans: IDBTransaction = db.transaction(dataBaseStore, "readwrite");      const store: IDBObjectStore = trans.objectStore(dataBaseStore);      const count: IDBRequest<number> = store.count();      // 计算记录的数量,增加前先查看是否超过限度      count.onsuccess = (): void => {        // 没超过就增加        if (Number(count.result) <= dataBaseLimit) {          //以主键log为key,把工夫戳和log作为value,插入数据库          store.put({ [dataBaseKeyPath]: `[${timeStamp}] : ${log}` });          return;        } else {          // 没超过就删除最老的一条          store.openCursor().onsuccess = (event: Event): void => {            const cursor: any = (event.target as IDBRequest).result;            if (cursor) {              cursor.delete();            }          };        }      };      // 计算记录的数量失败      count.onerror = (): void => {        console.log("Count Error");      };    };    // db关上失败    indexed.onerror = (): void => {      console.log("Indexed Open Error");    };  };  // 读取log  const readDBandExport = (): void => {    let tmp: string[] = [];    // 关上db    const indexed: IDBOpenDBRequest = indexedDB.open(dataBaseName);    indexed.onsuccess = (event: Event): void => {      const db: IDBDatabase = (event.target as IDBOpenDBRequest).result;      const trans: IDBTransaction = db.transaction(dataBaseStore, "readonly");      const store: IDBObjectStore = trans.objectStore(dataBaseStore);      // 遍历数据      store.openCursor().onsuccess = (event: Event): void => {        const cursor: any = (event.target as IDBRequest).result;        // 如果遍历项有数据就放入tmp,而后持续        if (cursor) {          tmp.push(cursor.key);          tmp.push("\r\n");          cursor.continue();        } else {          // 如果遍历项没有数据,阐明遍历完结,这时新建blob对象          const blob: Blob = new Blob(tmp, {            type: "text/plain;charset=utf-8",          });          // 导出文件          saveAs(blob, filename);        }      };      // 遍历数据失败      store.openCursor().onerror = (): void => {        console.log("OpenCursor Error");      };    };    // db关上失败    indexed.onerror = (): void => {      console.log("Indexed Open Error");    };  };  // 删除数据库  const deleteIndexedDB = (): void => {    const indexed: IDBOpenDBRequest = indexedDB.deleteDatabase(dataBaseName);    // 删除胜利    indexed.onsuccess = (): void => {      console.log("Delete Success");    };    // 删除失败    indexed.onerror = (): void => {      console.log("Delete Error");    };  };  // 调用  createIndexedDB();  // 测试  addLog("テスト");  return (    <main>      <h1>React.js</h1>      <button onClick={() => {addLog("ボタンからのテスト");}}>          addLog      </button>      <button onClick={readDBandExport}>readDBandExport</button>      <button onClick={deleteIndexedDB}>deleteIndexedDB</button>    </main>  );}export default App;

验证(以Vue.js为例)

启动我的项目后,发现数据库曾经建设

点击addLog增加测试数据,而后按readDBandExport导出

查看导出的文件,胜利

最初

如果须要联合捕捉console.log应用,请应用上面的函数

// log捕捉const catchConsoleLog = () => {  console.oldLog = console.log;  console.log = (log: string) => {    // 打印捕捉的log    console.oldLog(log);    addLog(log);  };};// 应用catchConsoleLog()