低代码编辑器 demo
前言
此低代码编辑器 demo,实现用意是让用户可以通过拖拉拽的形式,自行配置页面展示。
再做一下区分,由于业务性,不涉及到生成结构性代码生成,而是生成描述形式的 JSON,交由负责展示的项目或者模块翻译表达。
产品需求确认
我列出来的这些都需要和产品确认,如果有的话,没有产品,我们在开发前也需要明确:
二级页面、滚动页拖拽、悬浮重叠组件、组件内交互、参数量级、校验。
明确我们要做的大致内容,以及面临的挑战,这样在开发中才不会迷失方向。
接下来就是调研工作,低代码产品,不是一个新东西,很多公司都做过,我们可以取取经。
这里我一笔带过了~
技术路线/技术实现
实现一个 demo,效果为左侧拖拽组件,中间预览,右侧编辑 form。
左侧拖拽至右侧
左侧主要是组件的展示预览区域,一般会简要告诉用户该组件是做什么的,用户可以通过点击或拖拽添加至中间预览区编辑。其中涉及相对困难的点在于:
左侧拖拽至右侧,实现方案:
基于原生 drag 实现,没有找到合适的第三方支持
- 由于左侧本身应该不支持拖拽排序,而只是允许拖拽至右侧,并且组件并不会消失,这与多拖拽组件设计之初相违背,使用原生则会简单可拓展一些。
涉及难点:拖拽至中间时,存在多个组件,显示正确的预放置 drophere 站位符位置。
解决思路:由于每个 dragitem 都会有一个唯一值,在拖拽进入 dragOverItem 时可以获取到对应的 id,从而显示占位符。
预览主体
这里需要区分一下需要 y 轴排列拖拽滚动的长页面,和需要叠层任意拖拽的海报 h5 类的页面。
y 轴排列拖拽滚动的长页面:
主体拖拽实现,可以采用 @dnd-kit/core 或者 react-beautiful-dnd,我这里用的是 dnd-kit 对比 react-beautiful-dnd 暂时没有性能上的差距。
遇到的一些小 bug 的记录:
- 拖拽遮挡
问题原因:是未设置拖拽时 zindex 更高
- 非一致高度时,replace 高度继承 hoverItem 高度,导致拖动一个高度大的组件到高度小的组件位置时,空出的高度是小的,不容易看出来。
问题原因:CSS.Transform.toString(transform)会在移动元素时应用缩放到 X 和 Y 轴的变换。相反,使用 transform: CSS.Translate.toString(transform)可以解决这个问题。这是因为 CSS.Translate.toString(transform)会应用平移变换,而不会应用缩放变换。这样可以确保在拖动元素时不会出现缩放问题。
叠层任意拖拽的 h5 类的页面
主体拖拽实现,使用的第三方库 react-rnd,支持 resize 和 drag 控制。
主要功能实现在于其 onDragStop 时更新对应 id 的 x 与 y 值,onResizeStop 时更新 width 和 height。
还需优化的点:
前置功能需要完成多语言后台配置,而非后端配置。需要重新制定一套多语言方案。
右侧 form
可以对组件的样式, 逻辑, 交互进行配置,设计上主要在于数据存储和数据校验。
在数据结构设计和数据流这一块,单独放在后续文章中详细讲解。使用的是 zustand 存储数据,由 store 统一处理数据。
校验设计,简要概括:
- submit 提交时循环 value 触发对应的 validate 回调
- 找到所有校验不通过的 form,记录 id 和 cKey(组件唯一键)
- 切换到对应的组件 form
- 触发 form 的 onInit 触发 validateFields 保证 form 正确标红
待优化的点:
实际编写时,比较麻烦的是需要写两套校验,1 是 form 中的 rules,2 是 from 对应的校验回调函数,考虑是否可以合二为一。
产品设计上的优化,应保存奖品库或商品库,用时只需要添加并判断有无添加即可,而不需要判断其中的各种复杂的校验。
顶部功能区
功能包括:放回,页面名称,保存,预览(手机预览,需要校验数据),调试用 json 看板。
预览支持需要注意:需要验证数据,走保存逻辑,由后端生成的预览链接进行显示。
其他
公共组件库 OR 独立开发
公共组件库
- 优势:
- 单一源头
- 减少重复工作
- 方便进行组件的更新和维护
- 劣势:
- 维护成本高
- 开发成本高,需要考虑更多维情况
- 相对增加更多的代码体积
- 相对增加页面加载速度
独立开发,与公共组件库优劣相反。
从开发成本与以用户优先角度,最终还是选择*独立开发 *的方式。
性能考虑
- Dashboard 编辑处理速度
- 资源占用过高: 可视化开发平台通常提供了大量的可视化组件和功能,这些组件和功能可能会消耗大量的内存和计算资源。如果应用程序在内存高的情况下运行,可能会导致系统资源不足,从而影响平台的运行速度或导致假死。
- 复杂性和层次嵌套: 低代码平台通常支持复杂的应用程序开发,这可能导致应用程序的层次结构复杂,组件之间的嵌套层次深。当应用程序的层次嵌套非常深时,平台需要处理大量的组件和数据关系,这可能导致性能下降和假死现象。
- 数据量过大: 如果应用程序处理大量的数据,例如大型数据集或复杂的数据操作,这可能会占用大量的内存和计算资源。在内存高的情况下,系统可能无法有效地处理这些大量的数据,导致性能下降或假死。
- 可能的解决方案
- 优化资源使用: 确保应用程序和平台在设计和实现时充分优化资源的使用,避免资源的浪费和不必要的占用。
- 简化层次结构: 尽量简化应用程序的层次结构和组件嵌套,减少复杂性,提高性能。
- 处理大数据量: 对于大数据量的情况,采取适当的数据处理策略,如分页加载、服务器端数据处理等,以减轻客户端的资源压力。
- H5 渲染速度
- 图片资源压缩
- 动态组件加载
组件描述文件 json⭐
Item 数据类型:
{ |
{ |
store:
type State = { |
梳理字段
header 头:
- pageId:唯一
- pageName:用于标识编辑页面
左侧组件列需要数据:
- iconName: 用于图标显示,无需存元素
- title:描述组件标题
- cKey:唯一,通过 key 确定指向其对应组件
主体预览部分数据: key-value:cKey-component
- id:唯一,后端 id 或使用 uuid 生成的 id 值,唯一确定组件,一定要有不然排序和性能会有问题。
- cKey:组件对应 key 值,可能不唯一,添加相同组件。
- formValue:表单数据(实时改变)
- className:样式数据(实时改变)
配置区数据: key-value:cKey-from
- title(可能需要)
- initFormValue:表单初始数据
- initClassName:初始样式数据
类型定义
要求能规范到 key 和对应的 formValue,实例参考:
type CKey = "CKEY1" | "CKEY2" | "CKEY3" |