环境
- 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"; // 主 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("テスト");
</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()