indexbd的简单使用(crud)

简介

其实这不但单是个使用教程,同时我还做了idexdb的封装。

直接引用使用即可。

如果你不想理解库、表、记录的概念。

可以,因为我都默认给值了

你需要做的就是 

indexdbHelper.saveOrUpdate({xx:xx}) // 即可存储数据
indexdbHelper.remove() // 即可删除存储内容

 

核心代码(直接copy到你项目中)    indexdb-helper.js

// 默认数据库为myDB
// 默认表为global
// 记录的id不传,默认为global

let db = null;

const init = (tableName = 'global', dbName = 'myDB') => {
    // 使用 IndexedDB 的第一步是打开数据库
    const request = window.indexedDB.open(dbName);

    return new Promise((resolve, reject) => {
        request.onerror = function (event) { // 错误处理
            console.log(' 打开数据库报错');
            reject();
        };
        request.onsuccess = function (event) { // 成功处理
            db = event.target.result;
            createTable(tableName);
            console.log('打开数据库成功');
            resolve(db);
        };

        // 通过 监听[数据库升级事件]拿到 数据库实例
        request.onupgradeneeded = function (event) {
            db = event.target.result;
            createTable(tableName);
            console.log('onupgradeneeded');
            resolve(db);
        }
    })
}

// 创建表
const createTable = (tableName = 'global', keyPath = 'id') => {
    // 先判断一下,这张表格是否存在,如果不存在再新建
    if (!db.objectStoreNames.contains(tableName)) { // 创建一个人的表,id为主键
        db.createObjectStore(tableName, { keyPath });
    }
}

//
const save = (data, tableName = 'global') => {
    !data.id && (data.id = 'global')
    const request = db.transaction([tableName], 'readwrite').objectStore(tableName).add(data);
    return new Promise((resolve, reject) => {
        request.onsuccess = function (event) {
            console.log('数据写入成功');
            resolve(event);
        };
        request.onerror = function (event) {
            console.log('数据写入失败');
            reject(event);
        }
    })
}


//
const remove = (id = 'global', tableName = 'global') => {
    const request = db.transaction([tableName], 'readwrite')
        .objectStore(tableName)
        .delete(id);

    return new Promise((resolve, reject) => {
        request.onsuccess = function (event) {
            console.log('数据删除成功');
            resolve(true);
        };
        request.onerror = function (event) {
            console.log('数据删除失败');
            reject(event)
        };

    })

}

//
const update = (data, tableName = 'global') => {
    !data.id && (data.id = 'global')
    const request = db.transaction([tableName], 'readwrite')
        .objectStore(tableName)
        .put(data);

    return new Promise((resolve, reject) => {
        request.onsuccess = function (event) {
            console.log('数据更新成功');
            resolve(event);
        };
        request.onerror = function (event) {
            console.log('数据更新失败');
            reject(event);
        }
    })
}


// 新增或改(没有则插入,有则更新--必须包含主键,没有的话id默认为global)
const saveOrUpdate = async (data, tableName = 'global') => {
    !data.id && (data.id = 'global')
    const res = await read(data.id);
    if (res) {
        console.log('存在数据,即将更新')
        return update(data, tableName)
    } else {
        console.log('不存在数据,即将新增')
        return save(data, tableName)
    }
}


//
const read = (id = 'global', tableName = 'global') => {
    return new Promise((resolve, reject) => {
        const transaction = db.transaction([tableName]);
        var objectStore = transaction.objectStore(tableName);
        var request = objectStore.get(id);
        request.onerror = function (event) {
            console.log('事务失败');
            reject(event)
        };
        request.onsuccess = function (event) {
            if (request.result) {
                resolve(request.result)
            } else {
                console.log('未获得数据记录');
                resolve(null)
            }
        };
    })
}

// 查询所有(创建一个游标,类似JAVA里面的容器遍历的iterator()就是一个性能,估计发明IndexDB的作者可能的认真学过JAVA,这里纯属虚构,忽略,忽略...... )
const readAll = (tableName = 'global') => {
    return new Promise((resolve, reject) => {
        const objectStore = db.transaction(tableName).objectStore(tableName);
        const result = [];
        objectStore.openCursor().onsuccess = function (event) {
            const cursor = event.target.result;
            if (cursor) {
                const otherIf = {
                    db: cursor.source.transaction.db.name,
                    table: cursor.source.name
                }
                result.push({ value: cursor.value, otherIf });
                cursor.continue();
            } else {
                resolve(result)
            }
        };
    })
}


const indexdbHelper = {
    db, //数据库对象
    init, // 初始化数据库连接
    createTable, // 创建表(一般无需使用)
    save, // 插入记录(参数不传,默认为myDb库下global表中的 id为global的记录)
    update, // 更新记录(参数不传,默认为myDb库下global表中的 id为global的记录)
    saveOrUpdate,// 新增或更新
    read, // 查询(参数不传,默认为myDb库下global表中的 id为global的记录)
    readAll,// 查询指定表下的所有
    remove // 删除记录(参数不传,默认为myDb库下global表中的 id为global的记录)
}
window.indexdbHelper = indexdbHelper;
export default indexdbHelper;

 

 

使用方式

不管是vue还是react,都要在根实例初始化前,对indexDb初始化操作,这里拿react为例子   

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import indexdbHelper from './utils/indexdb-helper';



// indexdb连接成功后再初始化app
indexdbHelper.init().then((res)=>{
  ReactDOM.render(
    <App />,
    document.getElementById('root')
  );
  reportWebVitals();
})

 

开始使用

app.jsx

import './App.less';
import React, { useState, useEffect } from 'react';
import { Modal, Button, Card, Result, message } from 'antd';
import { codeMirrorOpt, jsonParse } from './utils/helper';
import indexdbHelper from './utils/indexdb-helper';
import { Controlled  as CodeMirror } from 'react-codemirror2';
require('codemirror/mode/javascript/javascript');


function App() {
  useEffect(() => {
    syncUsers();
  }, [])
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [users, setUsers] = useState([]);
  const [code, setCode] = useState('{}');
  const [btnAdd, setBtnAdd] =  useState(true);

  const syncUsers = async () => {
    const users = await indexdbHelper.readAll();
    console.log(users);
    setUsers(users);
  }

  const editUser = async (id) => {
    const user = await indexdbHelper.read(id);
    setBtnAdd(false);
    console.log(JSON.stringify(user));
    setCode(JSON.stringify(user));
    setIsModalVisible(true)
  }

  const addUser = async () => {
    setBtnAdd(true);
    setCode('{}');
    setIsModalVisible(true)
  }

  const deleteUser =  async (id) => {
    await indexdbHelper.remove(id);
    syncUsers();
  }



  // 弹窗配置项
  const modelHelper = {
    title: btnAdd?'新增记录':'编辑记录',
    visible: isModalVisible,
    async onOk() {
      const codeJson = jsonParse(code);
      if(!codeJson?.id){
        message.warning('id作为主键,必须存在。如果没有,默认为global');
      }
      // btnAdd?await indexdbHelper.save(codeJson):await indexdbHelper.update(codeJson);
      // 废弃上边的,用下边的我封装的牛逼方法
      await indexdbHelper.saveOrUpdate(codeJson)
      setIsModalVisible(false);
      syncUsers();
    },
    onCancel() {
      setIsModalVisible(false);
    }
  }

  // CodeMirror配置项
  const codeMirror = {
    value:code,
    options: codeMirrorOpt,
    onBeforeChange(editor, data, value) {
      setCode(value)
    }
  }

  return (
    <div className="App">
      {users.length > 0 ?
        <>
          <Button type="primary" onClick={addUser}>新增记录</Button>
          {users.map(({value: item,otherIf}) => {
            const title = `库${otherIf.db}--表${otherIf.table}--主键为${item.id}的一条记录`;
            return (<Card title={title} key={item.id} extra={<div>
              <a onClick={() => { editUser(item.id) }}>
                编辑
              </a>
              <a onClick={() => { deleteUser(item.id) }} style={{marginLeft:20}}>
                删除
              </a>
            </div>}>
              {JSON.stringify(item)}
            </Card>
          )})}

        </> :
        <Result
          status="warning"
          title="indexDB数据库的表无记录"
          extra={<Button type="primary" key="console" onClick={addUser}>
            前去新增
          </Button>}
        />
      }
      {isModalVisible && <Modal {...modelHelper}>
        <div>♥ 请输入json!</div>
        <CodeMirror {...codeMirror}/>
      </Modal>}
    </div>
  );
}

export default App;

 

helper.js

// 代码编辑器配置项
export const codeMirrorOpt = {
    mode: {
        name: 'text/javascript'
    },
    theme: 'material',
    lineNumbers: true
}

// 解析不规范的json
export const jsonParse = (str)=>{
    return eval("("+str+")");
}

 

代码

demo代码下载

https://gitee.com/dshvv/react-indexdb

 

 

 

效果

 

其它

如果你想用更全面的类库,推荐插件

http://localforage.docschina.org/

 

posted @ 2021-07-22 15:26  丁少华  阅读(717)  评论(0编辑  收藏  举报