前端本地存储之 indexedDB
发表于 2018年11月24日 1562次浏览
前言
关于前端本地存储,我一直停留在cookie
和localStorage
sessionStorage
,它们在存储一些简单的json数据是通常很有用。而认识indexedDB
是在日常的项目开发中,需要将一个zip
文件存储到本地(节省oss流量),虽然可以将文件转成二进制string
存入localStorage
中,但总感觉不伦不类,因此有了indexedDB
, 它不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。
实践
indexedDB
的DB
就能看到,它和数据库(database)有着某种关系,那么理解它就从增删改查开始吧。
把indexedDB的一些基本操作封装成基于promise的类
promise类库
module.exports = class IndexedDb {
constructor(){
this.db = {}
this.database = 'code'
this.form= 'codeCache'
this.dbInit = false
this.queryKey = 'courseId'
this.queryValue = 'blob'
}
init(){
const {database} = this
const request = indexedDB.open(database) //创建一个请求打开indexedDB
return new Promise((resolve,reject)=>{
request.onerror = (e)=> {
reject(e.target.error.message)
console.log('error: ',e)
}
request.onsuccess = (e)=> {
const db = e.target.result //数据库实例
this.db = db
this.dbInit = true
console.log('indexedDB init ok')
resolve(db)
}
request.onupgradeneeded = (e)=> {
const {form} = this
const db = e.target.result //数据库实例
if (!db.objectStoreNames.contains(form)) { //如果不存在这个表
const objectStore = db.createObjectStore(form, {
keyPath: 'id',
autoIncrement: true
})
objectStore.createIndex(this.queryKey, this.queryKey, {
unique: true
})
objectStore.createIndex(this.queryValue,this.queryValue,{
unique: false
})
}
console.log('onupgradeneeded: ok')
}
}).catch(err=>{
console.error(err)
})
}
add(key,value){
return new Promise((resolve,reject)=>{
const {dbInit,form,db,queryKey,queryValue} = this
const transaction = db.transaction(form,'readwrite') //创建一个事务
const selectedFrom = transaction.objectStore(form) //选择一个表
if(!dbInit){
reject('indexob 初始化失败')
}
const request = selectedFrom.add({
[queryKey]:key,
[queryValue]:value
})
request.onsuccess=(e)=>{
resolve(e)
}
request.onerror=(e)=>{
reject(e.target.error.message)
}
}).catch(err=>{
console.error(err)
})
}
async delete(key){
return new Promise(async (resolve,reject)=>{
const {id} = await this.query(key)
const {dbInit,form,db} = this
const transaction = db.transaction(form,'readwrite') //创建一个事务
const selectedFrom = transaction.objectStore(form) //选择一个表
if(!dbInit){
reject('indexob 初始化失败')
}
const request = selectedFrom.delete(id)
request.onsuccess=(e)=>{
resolve(e)
}
request.onerror=(e)=>{
reject(e.target.error.message)
}
}).catch(err=>{
console.error(err)
})
}
async update(courseId,blob){
return new Promise(async (resolve,reject)=>{
const oldData = await this.query(courseId)
const {dbInit,form,db,queryValue} = this
const transaction = db.transaction(form,'readwrite') //创建一个事务
const selectedFrom = transaction.objectStore(form) //选择一个表
if(!dbInit){
reject('indexob 初始化失败')
}
const newData = Object.assign(oldData,{
[queryValue]:blob
})
const request = selectedFrom.put(newData)
request.onsuccess=(e)=>{
resolve(e)
}
request.onerror=(e)=>{
reject(e.target.error.message)
}
}).catch(err=>{
console.error(err)
})
}
query(courseId){
return new Promise((resolve,reject)=>{
const {dbInit,form,db,queryKey} = this
const transaction = db.transaction(form,'readwrite') //创建一个事务
const selectedFrom = transaction.objectStore(form) //选择一个表
if(!dbInit){
reject('indexob 初始化失败')
}
const request = selectedFrom.index(queryKey).get(courseId)
request.onsuccess=(e)=>{
resolve(e.target.result)
}
request.onerror=(e)=>{
reject(e.target.error.message)
}
}).catch(err=>{
console.error(err)
})
}
}
基于此的react组件
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.scss'
import db from './indexedDB'
const IndexedDb = new db()
class Test extends Component{
constructor(props){
super(props)
this.state={
}
}
async componentDidMount(){
await IndexedDb.init()
}
add(key,value){
IndexedDb.add(key,value)
}
delete(key){
IndexedDb.delete(key)
}
update(key,value){
IndexedDb.update(key,value)
}
async query(key){
const data = await IndexedDb.query(key)
console.log(data)
}
render(){
return(
<div>
<div onClick={()=>this.add(123,'hello')}>增加</div>
<div onClick={()=>this.delete(123)}>删除</div>
<div onClick={()=>this.update(123,'hahahah')}>更新</div>
<div onClick={()=>this.query(123)}>查询</div>
</div>
)
}
}
ReactDOM.render(
<Test />,
document.getElementById('app')
)
后续
你们月更的博主又回来啦!!!哈哈哈哈