2023年做了表单设计器版本低代码表单设计器总结1,决心重构。
重构要求
-
增加数据源配置,主要是指数据源、SQL配置和过滤器
-
增加在线编辑器,前端直接编辑组件代码(template,script,css)和事件代码
-
增加对象(SQL,API,组件)生命周期函数和用户交互事件
-
增加后端nodejs支持在线编写接口逻辑
-
增加对象和组件动态参数计算逻辑
-
增加支持SSR和SPA
-
增加移动端适配
-
增加设计器和渲染器分离
-
增加Echarts和Three.js支持
-
同时支持表单、页面、大屏设计需求
-
全面性能优化
5种数据源设计
我定义数据源有这5种,分别是sql,http,websocket,nodejs,静态数据,我最开始定义数据库如下,每个类型有个表结构存储相关字段,但是我后来思考是否真的需要这样做,为什么不直接像第一版一样全都冗余到一个大字段json里面呢?我思考后觉得删除http和ws表,为什么呢?因为如果是后端要使用的数据比如sql是必须要单独存起来的,不然后端需要解析大json结构拿到配置数据,而http和ws这两种是前端使用的,直接用大json里面更容易。
数据库配置
首先可以先配置不同数据库连接,后面数据源支持sql,http,websocket(或mqtt),nodejs,静态数据五种
配置数据源是重要的,显而易见首先sql数据是必须要数据源的,第二http请求也是需要服务器源的,所以这里数据源也支持服务器地址配置,比如域名或者ip+端口,第三种是websocket源(mqtt源)
sql查询数据
sql数据其实也就是在后端有个统一执行的接口,但是sql内容依靠配置出来,也就是一种api接口简化写法。强调这里只支持select查询数据,不能支持CRUD其他语法。
很多产品是界面上选择表和字段可视化的方式,但是我考虑这种方式对于复杂查询语法比如多表联合查询来说,可视化界面就显得很鸡肋,还不如直接写sql查询来得方便,缺点就是需要sql知识基础。我考虑到用这个配置工具的人定位是开发人员。有了sql之后以后也可以扩展单表的可视化选择表和字段。
为什么要这么设计呢?
-
首先参数格式应该怎么定义,我这里用的
<name>
双尖括号表示变量,也有用$
和@
表示的,但是$name
和$name_jack
这会有歧义,可能是两个变量也可能是一个变量,我还是收尾括起来简单点 -
变量来源为什么有6种
-
sql的生命周期定义了4种,一类是前端执行的前后,二类是后端执行sql的前后。前端的前钩子可以用来修复参数,前端后钩子可以用来重构返回数据格式。后端前钩子可以用来校验参数格式或修改sql语句,后端后钩子可以修改返回到前端前数据内容。
这里我思考有几个问题要解决:
1、 orm 必然是必须的,我后端采用nest.js + typeorm,sql语句是有变量的,这个变量要解析成orm能识别的语句其中有一个转换过程
就是将select * from user where realname=$1 and age>$2 and alias like %$3%
转换成 select * from user where realname=$1 and age > $2 and alias like '%' || $1 || '%'
,其中like是最明显的
对于简单直接用replace替换字符串显而易见是最容易理解的,但是最好是用ast抽象语法树来做,node-sql-parser
就是做ast的,但是不支持mssql和oracle就很头疼。我还是直接用的字符串替换。
2、我们做数据源的数据库用的sqlite这很好,可以直接用orm,但是数据源是配置其他数据库的,比如mysql时,这要动态执行sql语句,我们用mysql2这个包
像下面这样使用,但是最好是使用连接池,但是连接池不能已开始就全局初始化,要等使用到这个数据源的时候才去初始化这个连接池,所以程序中会有多个连接池,因为配置了不同数据源的情况下。
import mysql from 'mysql2/promise';
async function main() {
// create the connection
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'test',
});
// query database
const [rows, fields] = await connection.execute(
'SELECT * FROM `table` WHERE `name` = ? AND `age` > ?',
['Morty', 14]
);
}
这里很麻烦的是处理like这样的语句,要做转换
3、第三个问题是拦截器,我们看流程,在nest.js中是可以做拦截器的,不然代码会冗余很大,在第二个问题中我们已经解决了后端执行sql这步,那用拦截器整合起来
http接口
这里要选服务器,大多数情况下都是同源服务器后端,但是有些情况是支持跨域服务器调用的。
http接口是最常用的一种,就是调后端接口,设计的事件就是请求前后钩子函数。
我认为需要引起重视的一点是,我们前端通常写接口会封装axios函数,会封装很多request和response拦截器里面会有很多逻辑判定比如token过期登出和各种提示框等,一般代码都是封装好了的,我们这里的http请求是否要走代码里面统一封装的axios函数呢,我认为是要走的,所以要提供一个配置项,可以使用代码统一封装的axios触发请求,这里要能提供配置支持。
静态数据
静态数据也是比较常用的,像一些状态值,
静态数据有两类,一种是根据字典值获取,第二类是手写配置数据
字典值需要先在系统管理中配置,再组件来选择一般是下拉框,单选框,复选框这些,key和value数组对象
更灵活的是手写配置数据,但是需要根据组件类型不同,写不同数据,但都是数组对象形式
比如下拉框和表格可以共用
[
{value: 1, label: '项目1'},
{value: 2, label: '项目2'},
]
比如树
[
{value: 1, label: '项目1',children:[{value: 3, label: '项目1-1'}]},
{value: 2, label: '项目2'},
]
nodejs数据
既然是nodejs,那么就知道这是在写后端代码了,在nodejs中可以做的事情太多,安全问题也是必须要考虑的。
可以操作sql拿药先提供一个sql数据源,可以操作服务器,可以获取三方接口
当然这里需要提供一些内置函数,比如取数据库连接函数等
我这里增加了字段,数据源选择,因为考虑到如果要在nodejs中连接数据库,也不能随便连,选择哪个就提供函数可以连这个,达到限制用户行为的目的
websocket数据
websocket看似没必要,其实很有必要,我用2023做的低代码平台做设备管理系统,设备的实时数据我只能通过轮训接口获取更新,但是对应的问题就是echarts图只能销毁冲毁,缺点很明显,这样支持websocket就有必要了
要去选择ws服务器,可以增加钩子函数处理获得数据后函数。