背景
公司低代码项目,对于设计器画布拖拽组件的情况,产品提出的极限测试的需求,场景下需要支持最大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");
}
最后
完整代码地址,戳这里