编辑器介绍

先来个图,有个初步的意识

道歉,原谅图有点含糊哈

github: https://github.com/Liberty-liu/Everright-formEditor

demo: https://everright.site/zh-cn/module/formEditor/introduction.html

Everright-formEditor是一个基于vue3的可视化编辑器,依赖于element-plusvant进行开发。外部提供了适配器进行参数转码。

  1. 灵便的拖放性能(通过拖拽便可决定一个字段插入行还是列,无需布局容器)
  2. 提供多种字段(单行文本、邮箱、身份证号、手机号、网址、多行文本、数字、单选框、多选框、工夫、日期、评分、开关、滑块、Html编辑器、级联、上传文件、签名、省市区)
  3. 布局字段(栅格布局、表格布局、标签页、折叠面板、分割线)
  4. 内置了国际化(中文和英文)
  5. 内置两种模式:字段与布局不拆散、字段与布局拆散
  6. 编辑器、预览器和属性面板都能够独自应用,能够依据理论需要选择性独自应用属性面板,满足不同场景下的需要

多图预警!!!多图预警!!!多图预警!!!多图预警!!!多图预警!!!多图预警!!!

编辑器界面

预览器pc界面

预览器mobile界面

属性面板界面

外部实现原理

Field

Field作为元素之一

在一个form编辑器里边,次要操作的是一个元素,布局容器(也是元素之一)则是作为Field的承载。用下图示意一个FieldField本身会有很多的属性。

留神右上角的的红色图案,示意这个Field外部属性由两个管道的输出来独特决定。

  1. 来自canvas面板canvas面板上面的选区(Selection)
  2. 来自属性面板配置属性

Field通过用户的click或者利落拽的形式塞入Canvas画板

Canvas

用下图示意一个Canvas画板

Canvas画板外部的数据用一个二维数组示意Array[r][c],设r为行,c为列,是不是有了一点table的滋味了,事实上如table一样的,外部能够有限嵌套的(布局容器是能够嵌套)。

当一个元素被插入Canvas画板元素会主动被 选区(Selection) 包裹。

选区(Selection)

用下图示意一个选区(Selection)

图中红色区域示意slot,元素被搁置在这个中央。

选区(Selection) 提供是否能够被拖拽、删除、复制、调整大小、选中父级的性能。

入选中元素时,会在Canvas面板上被高亮显示。

Config面板

用下图示意一个Config面板

用于配置字段属性。

入选中元素时,Config面板会显示被选中元素的本身的全副属性

数据流动图

联合以上示意图,将用户的行为用下图示意

  • 实线箭头代表用户的操作
  • 带圆点的实线箭头代表主动产生的事件
  • 虚线箭头示意数据流动

再加一段文字描述不便了解

  1. 当用户通过click或者利落拽的形式将一个元素拖入到画板当中,编辑器会主动为该元素包裹一个选区(Selection)
  2. 当用户选中选区的时候,Config面板会显示被选中元素的本身的全副属性
  3. 用户通过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的元素和实例来实现的。

现有性能缺点

  1. 历史记录
  2. 将tree构造界面体现进去(外部的数据有了)
  3. GUI形式管制字段显示与暗藏以及逻辑校验

以上性能接下来开发实现

低代码说白了就是一个堆性能的货色,全副都有了也就能力实现低代码