环境
- Windows 10
- Node.js
v18.0.0
- Yarn (用
npm
或pnpm
也没问题) - VS Code
- Chrome
前言
- 本教程间接给出办法,复制即可用。须要肯定的
indexedDB
的基础知识 - 办法中并没有应用异步,依据须要自行添加即可
- 尽管本教程给只出了
Vue
和React
两个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()