低代码可视化拖拽编辑器实现方案
前言
随着业务不断发展,低代码、无代码平台越来越常见,它降低开发门槛、快速响应业务需求、提升开发效率。零开发经验的业务人员通过可视化拖拽等方式,即可快速搭建各种应用。本文主要是讲解低代码可视化拖拽平台前端展示层面的实现逻辑和方案,对于后端逻辑、数据库设计、以及自动化部署等暂时没有涉及。
编码水平一般,提供给小伙伴们一些思路或学习参考。源码地址
展示区划分
首先我们需要先清晰我们要实现的UI展示效果,如下图,分为三部分(组件选项区、可视化展示区、元素配置编辑区)
1、组件选项区
1.1 数据格式定义
为了展示出各种元素,先定义元素的类型(文字、图片、按钮、banner、表单等等),具体数据格式如下,详情可以查看源码路径(src/config/template.ts、src/config/base.ts),这些组件的每一项也可以存储在库,通过接口查询回来,只是这里没有实现。
template.ts: 定义所有类型自定义组件的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82export const config: any = {
text: [
{
config: {
name: 'content-box',
noDrag: 1,
slot: [
{
name: 'content-input',
style: {
backgroundImage: require('@/assets/title1-left-icon.png'),
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
borderWidth: 0,
fontSize: '14px',
height: '13px',
lineHeight: '32px',
width: '18px'
},
value: ''
},
{
name: 'content-input',
style: {
height: '32px',
paddingLeft: '5px',
paddingRight: '5px'
},
value: "<div style=\"line-height: 2;\"><span style=\"font-size: 16px; color: #fce7b6;\"><strong>活动规则</strong></span></div>"
},
{
name: 'content-input',
style: {
backgroundImage: require('@/assets/title1-right-icon.png'),
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
borderWidth: 0,
fontSize: '14px',
height: '13px',
lineHeight: '32px',
marginRight: '5px',
width: '18px'
},
value: ''
}
],
style: {
alignItems: 'center',
backgroundColor: 'rgba(26, 96, 175, 1)',
display: 'flex',
height: '40px',
justifyContent: 'center',
paddingLeft: '1px'
},
value: ''
},
name: '带点的标题',
preview: require('@/assets/title1.jpg')
}
],
img: [
{
config: {
value: require('@/assets/gift.png'),
name: 'content-asset',
style: {
width: '100px',
height: '100px',
display: 'inline-block'
}
},
preview: require('@/assets/gift.png'),
name: '礼包'
}
],
btn: [
....
],
form: [
...
]
}
base.ts: 中定义基本组件的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33export const config: any = {
text: {
value: '<div style="text-align: center; line-height: 1;"><span style="font-size: 14px; color: #333333;">这是一行文字</span></div>',
style: {},
name: 'content-input'
},
multipleText: {
value: '<div style="text-align: center; line-height: 1.5;"><span style="font-size: 14px; color: #333333;">这是多行文字<br />这是多行文字<br />这是多行文字<br /></span></div>',
name: 'content-input',
style: {}
},
img: {
value: require('@/assets/logo.png'),
name: 'content-asset',
style: {
width: '100px',
height: '100px',
display: 'inline-block'
}
},
box: {
name: 'content-box',
noDrag: 0,
style: {
width: '100%',
minHeight: '100px',
height: 'auto',
display: 'inline-block',
boxSizing: 'border-box'
},
slot: []
}
}基本元素(文字content-input、图片content-asset)主要包含以下属性: name(组件名称)、style(行内样式)、value(内容值)
盒子元素(content-box)主要包含以下属性: name(组件名称)、style(行内样式)、noDrag(是否可拖拽)、slot(插槽内容
1.2 实现可拖拽
为了实现可拖拽效果,这里使用了sortable.js拖拽库来实现。更多使用细节可查看官方文档
关键实现代码如下:
1 |
|
1 |
|
这里主要讲一下onEnd里面的逻辑,当拖拽组件并将其移动到中间的可视化展示区的时候,需要做以下2个关键操作。
- 判断是否拖拽到可视化展示区内
- 获取当前拖拽元素的配置,并更新pinia中store的值。(pinia是vue新一代状态管理插件,可以认为是vuex5.)
1 |
|
2、可视化展示区
中间的可视化展示区的功能主要是提供用户对具体元素选中以及拖拽操作。因此主要实现元素展示 、选中框以及可拖拽功能。
2.1 元素展示
元素展示比较简单,只需要通过遍历pinia的store中的页面配置config,并用动态组件component标签展示即可
1 |
|
2.2 实现选中框
实现选中框的逻辑相对复杂一点,其中关键的两个事件是hover(鼠标悬浮在元素上)和select(鼠标点击元素)。
定义一个响应式对象来存储它们的变化情况:
1 |
|
定义事件监听器(mouseover、click)
1 |
|
定义修改catcher响应式对象方法
1 |
|
选中框组件
选中框组件包括选中框主体(通过不同颜色区分盒子还是元素)、功能栏(上下移动、删除、复制)。
1 |
|
比较关键的点是在操作功能栏的时候对全局配置的修改,详细逻辑可以查看源码(src/components/mouse-catcher/index.vue)
2.3 实现可视区拖拽
接下来是实现可视化展示区的可拖拽,这个区域与选项区不同,它允许内部元素的排序以及拖到别的拖拽组(盒子)。
关键逻辑如下:(主要分析onEnd回调中的逻辑)
1 |
|
2.4 实现盒子内拖拽
这里需要注意需要筛选可视区盒子subpage中类名为content-box,并且不包含类名为no-drag的。
其关键逻辑也是在onEnd回调函数里,需要区分元素在当前盒子内部移动、元素移动到其他盒子、元素移动到可视区(subpage)盒子三种情况。
1 |
|
3、元素配置编辑区
该区域是用于编辑修改元素的行内样式,目前简单实现了字体、位置布局、背景、边框、阴影配置。
3.1 字体编辑
字体编辑功能使用富文本编辑器tinymce,这里使用vue3-tinymce,它是基于 vue@3.x
+ tinymce@5.8.x
封装的富文本编辑器。
更多配置可参考官方文档, 下面的对vue3-tinymce进行封装。
1 |
|
3.2 位置布局
可修改元素的内外边距、宽高、布局类型(display)、定位类型(position)。
3.3 背景
可修改元素背景颜色、圆角、渐变方式。
3.4 边框
可修改边框类型,包括无边框、实线、虚线、点线
3.5 阴影
可修改阴影颜色、以及阴影的X、Y、距离、大小。
基础组件
1、文字组件
1 |
|
2、图片组件
1 |
|
3、盒子组件
1 |
|
到这里基本的实现流程都完毕,目前的版本还比较简单,还有很多可以实现的功能,比如撤回、重做、自定义组件选项、接入数据库.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!