Appearance
工作中常用方法 js 篇
封装 indexDB
封装 indexdb.js
js
// indexdb.js
class SkyDB {
indexedDB = null
dbName = null // 数据库名
storeName = null // 表名
db = null // 数据库对象
version = 1
constructor(dbName, storeName, version = 1) {
this.indexedDB =
window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB
if (!this.indexedDB) {
throw new Error('browser does not support indexedDB.')
}
if (!dbName) {
throw new Error('database name cannot be empty.')
}
this.dbName = dbName
if (!storeName) {
throw new Error('table name cannot be empty.')
}
this.storeName = storeName
this.version = version
}
openDatabase() {
return new Promise((resolve, reject) => {
let request = this.indexedDB.open(this.dbName, this.version)
// 每次页面刷新都会走这
request.onsuccess = (event) => {
// 拿到数据库对象
this.db = request.result
resolve()
}
request.onerror = (err) => {
reject(err)
}
// 监听第一次打开该数据库,或者数据库版本发生变化 事件
// 如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件,一般这里只会执行一次
request.onupgradeneeded = (event) => {
// 新建表和新建表的索引都必须在这个数据库中完成
this.db = event.target.result
// 判断是否有对应的表
if (!this.db.objectStoreNames.contains(this.storeName)) {
this.createStore()
} else {
this.deleteStore()
this.createStore()
}
}
})
}
// 删除数据库
deleteDatabase() {
this.indexedDB.deleteDatabase(this.dbName)
}
// 创建表
createStore() {
// 指定主键为一个递增的整数
let objectStore = this.db.createObjectStore(this.storeName, {
autoIncrement: true,
})
}
// 删除表
deleteStore() {
this.db.deleteObjectStore(this.storeName)
}
async set(key, value) {
try {
const res = await this.get(key)
const data = value === undefined ? null : value
// 如果查到有数据,则走更新逻辑
// 这里使用 undefined 的原因是,没有数据返回的就是 undefined
if (res === undefined) {
await this.add(key, data)
} else {
await this.put(key, data)
}
} catch (error) {
throw new Error(error)
}
}
// 往表添加数据
add(key, value) {
return new Promise((resolve, reject) => {
// 开启一个事务,并拿到IDBObjectStore 对象
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.add(value, key)
result.onsuccess = () => {
resolve()
}
result.onerror = () => {
reject()
}
})
}
// 更新表中的数据
put(key, value) {
return new Promise((resolve, reject) => {
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.put(value, key)
result.onsuccess = () => {
resolve()
}
result.onerror = () => {
reject()
}
})
}
// 查询表中数据
get(key) {
return new Promise((resolve, reject) => {
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.get(key)
result.onsuccess = () => {
const res = result.result
if (res || typeof res === 'boolean') {
resolve(res)
} else {
resolve()
}
}
result.onerror = () => {
reject()
}
})
}
// 查询表中所有数据
getAll() {
return new Promise((resolve, reject) => {
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.getAll()
result.onsuccess = () => {
const res = result.result
if (res || typeof res === 'boolean') {
resolve(res)
} else {
resolve()
}
}
result.onerror = () => {
reject()
}
})
}
// 删除表中数据
delete(key) {
return new Promise((resolve, reject) => {
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.delete(key)
result.onsuccess = () => {
resolve()
}
result.onerror = () => {
reject()
}
})
}
// 清空表
clear() {
return new Promise((resolve, reject) => {
let objectStore = this.db
.transaction([this.storeName], 'readwrite')
.objectStore(this.storeName)
let result = objectStore.clear()
result.onsuccess = () => {
resolve()
}
result.onerror = () => {
reject()
}
})
}
}
使用
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>indexdb</title>
<style>
* {
margin: 0;
padding: 0;
}
.list {
float: left;
width: 50%;
display: flex;
align-items: center;
margin-top: 20px;
}
button {
cursor: pointer;
width: 100px;
height: 40px;
margin-left: 20px;
}
textarea {
width: 200px;
height: 40px;
padding: 10px;
margin-left: 20px;
}
input[type='text'] {
width: 120px;
height: 20px;
padding: 10px;
margin-left: 20px;
}
input[type='checkbox'] {
cursor: pointer;
margin-left: 20px;
}
.warning {
color: #ffffff;
border-color: #f56c6c;
background-color: #f56c6c;
outline: none;
}
.content {
min-height: 200px;
margin-top: 20px;
padding: 10px;
line-height: 20px;
background-color: #f56c6c;
}
</style>
</head>
<body>
<div class="list">
<button onclick="init()">初始化db</button>
<input type="text" id="one" placeholder="输入表名" />
</div>
<div class="list">
<button onclick="handleAdd()">添加修改数据</button>
<input type="text" id="two" placeholder="输入 key" />
<textarea id="three" placeholder="输入 value"></textarea>
<div>
例子: <br />
1、 {"name": "123", "age": 18}/object <br />
2、 true/boolean <br />
3、 12335464/number <br />
4、 dgdfg34gfdg
</div>
</div>
<div class="list">
<button class="warning" onclick="handleDelete()">删除数据</button>
<input type="text" id="seven" placeholder="输入 key" />
</div>
<div class="list">
<button onclick="handleGet()">获取数据</button>
<input type="text" id="six" placeholder="输入 key" />
</div>
<div class="list">
<button class="warning" onclick="handleClear()">清空数据</button>
</div>
<br clear="all" />
<div class="content" id="content"></div>
<script src="./indexdb.js"></script>
<script>
let db = null
async function init() {
const val = document.getElementById('one').value
const arr = val.split(',')
if (arr.length > 1) {
db = new SkyDB('test', arr[0], Number(arr[1]))
} else {
db = new SkyDB('test', arr[0])
}
await db.openDatabase()
}
async function handleAdd() {
const key = document.getElementById('two').value
const val = document.getElementById('three').value
const arr = val.split('/')
if (arr.length > 1) {
if (arr[1] === 'number') {
await db.set(key, Number(arr[0]))
} else if (arr[1] === 'object') {
await db.set(key, JSON.parse(arr[0]))
} else if (arr[1] === 'boolean') {
await db.set(key, arr[0] === 'true' ? true : false)
}
} else {
await db.set(key, val)
}
}
async function handleGet() {
const key = document.getElementById('six').value
const res = await db.get(key)
document.getElementById('content').innerText = typeof res + '--' + res
}
async function handleDelete() {
const key = document.getElementById('seven').value
await db.delete(key)
}
async function handleClear() {
await db.clear()
}
</script>
</body>
</html>