indexedDB愉快使用体检,dexie二次封装

658 阅读3分钟

背景

公司低代码项目,对于设计器画布拖拽组件的情况,产品提出的极限测试的需求,场景下需要支持最大50个图层,每个图层最多400个组件。

不考虑这种需求合不合理,第一要务从技术角度去解决(懒得扯皮...)

那对于测试同事来说,手动拖拽组件达到极限测试的要求,无疑是不人性的,那人性的考虑就是,模拟场景数据的工作落在前端的头上。

目前低代码组件一共62个,挨个拖一遍到画布中,最终生成的场景JSON数据有存储在本地,从LocalStorage中取到这份JSON,通过一个脚本,循环50个图层,每个图层中组件数据循环复制,超出400个结束,最终数据生成一份JSON文件。

那之前将场景数据存储到LocalStorage以供预览使用,这样的数据量就不支持了。

indexedDB

IndexedDB 是一个事务型数据库系统。参考MDN,戳这里,可以详细学习,这里默认各位已经了解,是想着找一篇可以快速入手的教程。

dexie.js

原生indexedDB操作起来稍显复杂,indexedDB的第三方库我采用了dexie。

详细了解dexie,参考官网,戳这里

那其实对于数据库,想愉快简单的使用需求也就是如何增删改查。

新建一个db.js,基于dexie封装一个类。

初始化数据库

import Dexie from "dexie";
export class lowCodeDB extends Dexie {
  constructor() {
    super("previewData");
    this.version(1).stores({
      scenes: "++id, code, data",
    });
  }
}
export const db = new lowCodeDB();

新建一个previewData的数据库,一张scenes的表,自增的id字段,code和data字段是根据自己业务定义,我这儿设计器中场景数据用来预览使用,code是预览是生成的唯一值,data里存放场景JSON数据。

本地的IndexedDB就会如下这样生成:

查询

export class lowCodeDB extends Dexie {
  ...
  async query_code(code) {
    const res = await this.scenes
      .where("code")
      .equalsIgnoreCase(code)
      .toArray();
    return res[0];
  }
}

依据唯一值code查询数据,where条件查询code字段,传入需要查询的code,最终以数组形式返回。

使用

import { db } from "./db";
async function getItem() {
  const res = await db.query_code("previewCode1");
  console.log("默认已存在code为previewCode1的数据,新增会在下面讲到", res);
}

更新

  async update(code, params) {
    const { id } = await this.query_code(code);
    await this.scenes.put({ id, ...params });
  }

id是dexie自身更新api需要的参数,它是根据自增id字段进行查询,但我业务上其实并不涉及到这个id,我需要的是code,因为这样封装方便传入code更新。

使用

function update() {
  db.update("previewCode1", {
    code: "previewCode2",
    data: JSON.stringify({ id: 1, pageType: true, list: [{ name: 1111 }] }),
  });
}

新增

  async add(params) {
    const { code } = params;
    const targetItem = await this.query_code(code);
    if (targetItem) {
      this.update(targetItem.code, params);
    } else {
      await this.scenes.add(params);
    }
  }

新增数据中code已存在就走更新逻辑,否则就是追加一条新数据。

使用

function add() {
  db.add({
    code: "previewCode1",
    data: JSON.stringify({ id: 1, pageType: true, list: [{ name: 1111 }] }),
  });
}

删除

  async delete(code) {
    const { id } = await this.query_code(code);
    await this.scenes.delete(id);
  }

和更新一样的考虑,需要通过code来进行删除。

使用

function delItem() {
  db.delete("previewCode1");
}

最后

完整代码地址,戳这里