编辑器介绍
先来个图,有个初步的意识
道歉,原谅图有点含糊哈
github: https://github.com/Liberty-liu/Everright-formEditor
demo: https://everright.site/zh-cn/module/formEditor/introduction.html
Everright-formEditor是一个基于vue3的可视化编辑器,依赖于element-plus和vant进行开发。外部提供了适配器进行参数转码。
- 灵便的拖放性能(通过拖拽便可决定一个字段插入行还是列,无需布局容器)
- 提供多种字段(单行文本、邮箱、身份证号、手机号、网址、多行文本、数字、单选框、多选框、工夫、日期、评分、开关、滑块、Html编辑器、级联、上传文件、签名、省市区)
- 布局字段(栅格布局、表格布局、标签页、折叠面板、分割线)
- 内置了国际化(中文和英文)
- 内置两种模式:字段与布局不拆散、字段与布局拆散
- 编辑器、预览器和属性面板都能够独自应用,能够依据理论需要选择性独自应用属性面板,满足不同场景下的需要
多图预警!!!多图预警!!!多图预警!!!多图预警!!!多图预警!!!多图预警!!!
编辑器界面
预览器pc界面
预览器mobile界面
属性面板界面
外部实现原理
Field
Field作为元素之一
在一个form编辑器里边,次要操作的是一个元素,布局容器(也是元素之一)则是作为Field的承载。用下图示意一个Field,Field本身会有很多的属性。
留神右上角的的红色图案,示意这个Field外部属性由两个管道的输出来独特决定。
- 来自canvas面板、canvas面板上面的选区(Selection)
- 来自属性面板配置属性
Field通过用户的click或者利落拽的形式塞入Canvas画板
Canvas
用下图示意一个Canvas画板
Canvas画板外部的数据用一个二维数组示意Array[r][c]
,设r为行,c为列,是不是有了一点table的滋味了,事实上如table一样的,外部能够有限嵌套的(布局容器是能够嵌套)。
当一个元素被插入Canvas画板,元素会主动被 选区(Selection) 包裹。
选区(Selection)
用下图示意一个选区(Selection)
图中红色区域示意slot,元素被搁置在这个中央。
选区(Selection) 提供是否能够被拖拽、删除、复制、调整大小、选中父级的性能。
入选中元素时,会在Canvas面板上被高亮显示。
Config面板
用下图示意一个Config面板
用于配置字段属性。
入选中元素时,Config面板会显示被选中元素的本身的全副属性
数据流动图
联合以上示意图,将用户的行为用下图示意
- 实线箭头代表用户的操作
- 带圆点的实线箭头代表主动产生的事件
- 虚线箭头示意数据流动
再加一段文字描述不便了解
- 当用户通过click或者利落拽的形式将一个元素拖入到画板当中,编辑器会主动为该元素包裹一个选区(Selection)
- 当用户选中选区的时候,Config面板会显示被选中元素的本身的全副属性
- 用户通过Config面板或者选区(Selection) 批改元素属性的时候,数据会同步到Canvas画板,实现所见即所得
适配器(Adapter)
用下图示意一个适配器(Adapter)
因为pc依赖element-plus,mobile依赖vant,它们之间交加局部的性能参数有些是不一样的,适配器(Adapter) 就是做这个体力活的。
举个栗子
Rate评分这个组件想设置一下星星⭐️的数量,在element-plus参数是max,而在vant是count。
上面插入一点点代码示意一下适配器所做的事件
if (!isPc) { result.count = options.max} else { result.max = options.max}
编辑器的两种模式
再回顾一下在编辑器外部流动的次要数据是元素,元素分为字段和布局容器。
编辑器外部的实在数据是一个tree。
默认状况下,编辑器是采纳布局和字段不拆散的模式,当然,也反对布局和字段拆散的模式。
layoutType1 布局和字段不拆散
在PC端设计表单,会自适应mobile端。
layoutType2 布局和字段拆散
在PC端设计表单时,例如将一个字段为email的字段放入到tabs容器中,切换到mobile端,不会同步tabs容器的,此时如果在mobile新建一个Collapse容器,将email字段放入其中,切换到pc端,是不会同步Collapse容器的,对于在一端新增的字段,切换到另一端,会进行两个汇合运算,新增的字段会push到画板底部,删除的字段会在布局构造体中删除掉。字段本身的所有属性是同步的。
以上无论哪种模式,导出的数据都会把Field抽离进去的,与后端而言,他们更关怀的是字段而非是一个tree。
拖拽逻辑
依赖sortablejs来实现的,然而用sortablejs想做到插入行或者列是不反对的。插入行的时候再包裹一个inline容器(元素插入一行会主动包裹一个inline虚构容器),当行内惟一元素被挪动走,又得删除inline容器,简而言之就是当拖拽一个元素,如果插入行就会包裹一个inline容器,如果插入列就插入到inline容器下边。
因而写了一个sortablejs的插件拦挡了dragOver和drop事件来实现的。
当拖拽的时候会始终触发dragOver事件,依据以后鼠标的x/y判断在target元素的四个方向决定是插入行还是列,判断四个方向是依据斜率计算的,贴一张图比拟容易了解。挡drop的时候记录最初一次dragOver的元素和实例来实现的。
现有性能缺点
- 历史记录
- 将tree构造界面体现进去(外部的数据有了)
- GUI形式管制字段显示与暗藏以及逻辑校验
以上性能接下来开发实现
低代码说白了就是一个堆性能的货色,全副都有了也就能力实现低代码