• indexedDB的简单使用


    今天想写一篇关于indexedDB的文章,由于最近项目需要前端存储数据,但是localStorage存储空间有限,最后综合考虑采用indexedDB来存储。本文将简单介绍一下indexedDB的使用场景,以及简单的封装。IndexedDB是一个基于JavaScript的面向对象数据库,他是一个事务型数据库系统,事务型数据库与关系型数据库的区别呢,这里就不多做介绍了。直接切入正文吧。

    1、indexedDB的优点:

    1. 键值对存储,方便。

    2. 异步操作,不会导致主流程卡顿,影响用户体验。

    3. 支持存储对象,字符串,二进制数据。

    2、主要流程:

    打开数据库( indexedDB.open() )>创建数据仓库( db.createObjectStore() )>创建一个事务,链接数据仓库( db.transaction([storeName]).objectStore(storeName) )>对数据增删改查( stroe.add()、store.put()、store.delete()、store.get() )>关闭数据库( db.close() )。

    数据的获取方式有三种:

    1、使用getAll()获取所有数据。

    2、使用get(key)获取单条数据,这里的key是要获取数据的主键的值。

    3、使用openCursor(),这是indexedDB的指针对象,他也是异步的所以监听success方法,然后使用cursor.contiune()移动指针。

    3、封装:

    interface MsgProps {
      type: string,
      message: string | object
    }
    export default class DB {
      dbName: string
      db: any
      constructor(name: string) {
        this.dbName = name
      }
    
      open(storeName: string, keyPath: string, indexs?: Array<string>) {
        if(!window.indexedDB) {
          return alert('您的浏览器不支持该app,为了更好的体验,请使用新版chrome浏览器')
        }
        const request = window.indexedDB.open(this.dbName, new Date().getTime())
        return new Promise((resolve, rej) => {
          request.onerror = (e: any) => {
            this.onmessage({type: '数据库连接失败', message: e})
            rej()
          }
          request.onsuccess = (e: any) => {
            this.db = e.target.result
            this.onmessage({type: '数据库连接成功', message: ''})
            resolve()
          }
          request.onupgradeneeded = (e: any) => {
            const db = e.target.result
            if(!db.objectStoreNames.contains(storeName)) {
              const store = db.createObjectStore(storeName, {autoIncrement: true, keyPath})
              if(indexs && indexs.length) {
                indexs.map((v) => {
                  store.createIndex(v, v, { unique: false })
                })
              }
              store.transaction.oncomplete = (ev: any) => {
                this.onmessage({type: '创建对象仓库成功', message: ''})
              }
            }
          }
        })
        
      }
    
      onmessage(msg: MsgProps) {
        console.log(msg.type, msg.message)
      }
    
      update(storeName: string, data: object) {
        const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
        return new Promise((resolve, rej) => {
          const request = store.put({
            ...data,
            lastModify: new Date().getTime()
          })
          request.onsuccess = (e: any) => {
            this.onmessage({
              type: '更新成功',
              message: data
            })
            resolve()
          }
          request.onerror = (e: any) => {
            this.onmessage({
              type: '更新失败',
              message: data
            })
            rej()
          }
        })
      }
    
      getList(storeName: string) {
        const store = this.db.transaction([storeName]).objectStore(storeName)
        return new Promise((resolve, rej) => {
          store.getAll().onsuccess = (e: any) => {
            const res = e.target.result
            this.onmessage({
              type: '获取列表成功',
              message: res
            })
            resolve(res)
          }
        })
      }
    
      getItem(storeName: string, key: string) {
        const store = this.db.transaction(storeName).objectStore(storeName)
        return new Promise((resolve, rej) => {
          const request = store.get(key)
          request.onsuccess = (e: any) => {
            resolve(e.target.result)
          }
          request.onerror = (e: any) => {
            rej()
          }
        })
      }
    
      delete(storeName: string, key: string) {
        const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
        const request = store.delete(key)
        return new Promise((resolve, rej) => {
          request.onsuccess = (e: any) => {
            this.onmessage({
              type: '删除成功',
              message: key
            })
            resolve()
          }
          request.onerror = (e: any) => {
            this.onmessage({
              type: '删除失败',
              message: data
            })
            rej()
          }
        })
        
      }
    
      closeDB() {
        this.db.close()
      }
    
      deleteDB() {
        indexedDB.deleteDatabase(this.dbName)
      }
    
    }

    如上所示,由于indexedDB的put会在没有找到的时候创建一条数据,找到的话更新这条数据。所以没有封装post方法。对于indexedDB来说没有数据表的概念,它是根据数据库版本号来管理对象残酷的。

    注意:打开数据库的时候,只有版本号改变,才可以在该数据库中创建对象仓库。本人这里偷了个懒,直接使用时间戳作为版本号,请大家自行改进优化。

  • 相关阅读:
    Redis
    双向绑定篇
    Vue篇1
    css篇-页面布局-三栏布局
    css篇-简化版
    Promise篇
    几道JS代码手写面试题
    安全篇
    Vue篇
    跨域篇--JSONP原理
  • 原文地址:https://www.cnblogs.com/marvey/p/13216048.html
Copyright © 2020-2023  润新知