前端本地存储之 indexedDB

前言

关于前端本地存储,我一直停留在cookielocalStorage sessionStorage,它们在存储一些简单的json数据是通常很有用。而认识indexedDB是在日常的项目开发中,需要将一个zip文件存储到本地(节省oss流量),虽然可以将文件转成二进制string存入localStorage中,但总感觉不伦不类,因此有了indexedDB, 它不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

实践

indexedDBDB就能看到,它和数据库(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')
)

后续

你们月更的博主又回来啦!!!哈哈哈哈