Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
datax-cloud
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
黄营
datax-cloud
Commits
419077c4
Commit
419077c4
authored
Jan 03, 2021
by
yuwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update: 智能表单代码
parent
6e32cec9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1875 additions
and
0 deletions
+1875
-0
package.json
datax-ui/package.json
+1
-0
index.js
datax-ui/src/router/index.js
+6
-0
form-design.scss
datax-ui/src/styles/form-design.scss
+374
-0
FormDesign.vue
datax-ui/src/views/dynamicform/formmaking/FormDesign.vue
+102
-0
WidgetDraggableItem.vue
...dynamicform/formmaking/components/WidgetDraggableItem.vue
+389
-0
WidgetForm.vue
...rc/views/dynamicform/formmaking/components/WidgetForm.vue
+88
-0
WidgetFormItem.vue
...iews/dynamicform/formmaking/components/WidgetFormItem.vue
+292
-0
componentsConfig.js
...c/views/dynamicform/formmaking/config/componentsConfig.js
+608
-0
index.vue
datax-ui/src/views/dynamicform/index.vue
+15
-0
No files found.
datax-ui/package.json
View file @
419077c4
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
"vue-draggable-resizable-gorkys"
:
"^2.4.4"
,
"vue-draggable-resizable-gorkys"
:
"^2.4.4"
,
"vue-grid-layout"
:
"^2.3.11"
,
"vue-grid-layout"
:
"^2.3.11"
,
"vue-router"
:
"3.0.6"
,
"vue-router"
:
"3.0.6"
,
"vue2-editor"
:
"^2.10.2"
,
"vuedraggable"
:
"^2.24.0"
,
"vuedraggable"
:
"^2.24.0"
,
"vuex"
:
"3.1.0"
"vuex"
:
"3.1.0"
},
},
...
...
datax-ui/src/router/index.js
View file @
419077c4
...
@@ -97,6 +97,12 @@ export const constantRoutes = [
...
@@ -97,6 +97,12 @@ export const constantRoutes = [
},
},
{
{
path
:
'/form/making'
,
component
:
()
=>
import
(
'@/views/dynamicform/formmaking/FormDesign'
),
hidden
:
true
},
{
path
:
'/'
,
path
:
'/'
,
component
:
Layout
,
component
:
Layout
,
redirect
:
'/dashboard'
,
redirect
:
'/dashboard'
,
...
...
datax-ui/src/styles/form-design.scss
0 → 100644
View file @
419077c4
.form-design-container
{
height
:
100vh
;
width
:
100%
;
margin
:
0
;
padding
:
0
;
::-webkit-scrollbar
{
width
:
3px
;
height
:
5px
;
}
::-webkit-scrollbar-track-piece
{
background
:
#d3dce6
;
}
::-webkit-scrollbar-thumb
{
background
:
#99a9bf
;
border-radius
:
10px
;
}
.form-design-content
{
height
:
100%
;
background
:
#fff
;
// 左右栏
aside
{
box-shadow
:
0px
0px
1px
1px
#ccc
;
height
:
100%
;
// 左侧区域
&
.left
{
height
:
100%
;
overflow
:
auto
;
user-select
:
none
;
.widget-cate
{
padding
:
12px
;
font-size
:
14px
;
}
ul
{
position
:
relative
;
overflow
:
hidden
;
padding
:
0
10px
10px
;
margin
:
0
;
li
{
font-size
:
12px
;
display
:
block
;
width
:
48%
;
line-height
:
26px
;
position
:
relative
;
float
:
left
;
left
:
0
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
margin
:
1%
;
color
:
#333
;
border
:
1px
solid
#F4F6FC
;
&
:hover
{
color
:
#409eff
;
border
:
1px
solid
#409eff
;
position
:
relative
;
z-index
:
1
;
box-shadow
:
0
2px
6px
#409eff
;
}
&
>
a
{
display
:
block
;
cursor
:
move
;
background
:
#F4F6FC
;
border
:
1px
solid
#F4F6FC
;
.icon
{
margin-right
:
6px
;
margin-left
:
8px
;
font-size
:
14px
;
display
:
inline-block
;
vertical-align
:
middle
;
}
span
{
display
:
inline-block
;
vertical-align
:
middle
;
}
}
}
}
}
// 右侧区域
&
.right
{
height
:
100%
;
color
:
#fff
;
overflow
:
hidden
;
position
:
relative
;
}
}
// 中间内容区域
.widget-center-container
{
border-left
:
1px
solid
#e0e0e0
;
border-right
:
1px
solid
#e0e0e0
;
.btn-bar
{
height
:
45px
;
line-height
:
45px
;
font-size
:
18px
;
border-bottom
:
2px
solid
#e4e7ed
;
text-align
:
right
;
}
// 内容操作区域
.el-main
{
padding
:
0
;
position
:
relative
;
background
:
#fafafa
;
.widget-form-wrapper
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
::v-deep
.el-form
{
height
:
100%
;
.form-empty
{
position
:
absolute
;
left
:
0
;
top
:
45%
;
width
:
100%
;
text-align
:
center
;
font-size
:
20px
;
color
:
#aaa
;
}
.draggable-box
{
height
:
100%
;
overflow
:
auto
;
.draggable-list
{
min-height
:
100%
;
padding
:
5px
;
position
:
relative
;
background
:
#fafafa
;
.moving
{
// 拖放移动中
background
:
#409EFF
;
border
:
2px
solid
#409EFF
;
outline-width
:
0
;
height
:
3px
;
box-sizing
:
border-box
;
font-size
:
0
;
content
:
''
;
overflow
:
hidden
;
padding
:
0
;
}
.draggable-move
{
border
:
1px
dashed
hsla
(
0
,
0%
,
66
.7%
,.
5
);
background-color
:
rgba
(
236
,
245
,
255
,.
3
);
.draggable-move-box
{
position
:
relative
;
box-sizing
:
border-box
;
padding
:
8px
;
overflow
:
hidden
;
transition
:
all
.3s
;
min-height
:
36px
;
&
:hover
{
background
:
#ecf5ff
;
}
&
:
:
before
{
content
:
''
;
height
:
5px
;
width
:
100%
;
background
:
#13c2c2
;
position
:
absolute
;
top
:
0
;
right
:
-100%
;
transition
:
all
.3s
;
}
&
.active
{
&
:
:
before
{
right
:
0
;
}
background
:
#ecf5ff
;
outline-offset
:
0
;
}
&
.is_hidden
{
background
:
#fef0f0
;
}
.form-item-box
{
position
:
relative
;
box-sizing
:
border-box
;
word-wrap
:
break-word
;
&
:
:
before
{
content
:
""
;
position
:
absolute
;
width
:
100%
;
height
:
100%
;
top
:
0
;
left
:
0
;
z-index
:
888
;
}
.el-form-item
{
margin-bottom
:
5px
;
}
&
.is_req
{
.
el-form-item__label
:
:
before
{
content
:
'*'
;
color
:
#f56c6c
;
margin-right
:
4px
;
}
}
}
.widget-view-action
{
position
:
absolute
;
right
:
0
;
bottom
:
0
;
height
:
28px
;
line-height
:
28px
;
background
:
#409eff
;
z-index
:
9
;
i
{
font-size
:
14px
;
color
:
#fff
;
margin
:
0
5px
;
cursor
:
pointer
;
}
}
.widget-view-drag
{
position
:
absolute
;
left
:
0px
;
top
:
0px
;
height
:
28px
;
line-height
:
28px
;
background
:
#409eff
;
z-index
:
9
;
i
{
font-size
:
14px
;
color
:
#fff
;
margin
:
0
5px
;
cursor
:
move
;
}
}
.widget-view-model
{
position
:
absolute
;
top
:
10px
;
right
:
10px
;
font-size
:
12px
;
color
:
#13c2c2
;
z-index
:
9
;
font-weight
:
500
;
}
}
.subform-box
,
.tabs-box
,
.grid-box
,
.table-box
,
.card-box
{
position
:
relative
;
box-sizing
:
border-box
;
padding
:
5px
;
background
:
rgba
(
253
,
246
,
236
,.
3
);
width
:
100%
;
transition
:
all
.3s
;
overflow
:
hidden
;
&
:hover
{
background
:
rgba
(
152
,
103
,
247
,
0
.24
);
}
.subform-label
{
font-size
:
16px
;
font-weight
:
500
;
padding
:
10px
20px
;
}
.form-item-box
{
position
:
relative
;
box-sizing
:
border-box
;
}
.draggable-box
{
min-height
:
60px
;
min-width
:
50px
;
border
:
1px
#ccc
dashed
;
background
:
#fff
;
.draggable-list
{
min-height
:
60px
;
position
:
relative
;
border
:
1px
#ccc
dashed
;
}
}
&
:
:
before
{
content
:
''
;
height
:
5px
;
width
:
100%
;
background
:
transparent
;
position
:
absolute
;
top
:
0
;
right
:
-100%
;
transition
:
all
.3s
;
}
&
.active
{
&
:
:
before
{
background
:
#9867f7
;
right
:
0
;
}
background
:
rgba
(
152
,
103
,
247
,
0
.24
);
outline-offset
:
0
;
}
.table-layout
{
background
:
rgba
(
152
,
103
,
247
,
0
.12
);
width
:
100%
;
box-sizing
:
border-box
;
transition
:
all
0
.3s
;
border-collapse
:
collapse
;
tr
{
transition
:
all
0
.3s
;
border-collapse
:
collapse
;
td
{
box-sizing
:
border-box
;
transition
:
all
0
.3s
;
padding
:
12px
12px
;
border-collapse
:
collapse
;
vertical-align
:top
;
}
}
&
.bordered
{
// 添加边框
tr
{
td
{
border
:
1px
solid
#e8e8e8
!
important
;
}
}
}
&
.bright
{
// 点亮行
tr
{
&
:hover
>
td
{
background
:
#e6f7ff
;
}
}
}
&
.small
{
// 紧凑型
tr
{
td
{
padding
:
8px
8px
;
}
}
}
}
>
.widget-view-action
{
position
:
absolute
;
right
:
0
;
bottom
:
0
;
height
:
28px
;
line-height
:
28px
;
background
:
#9867f7
;
z-index
:
9
;
i
{
font-size
:
14px
;
color
:
#fff
;
margin
:
0
5px
;
cursor
:
pointer
;
}
}
>
.widget-view-drag
{
position
:
absolute
;
left
:
0px
;
top
:
0px
;
height
:
28px
;
line-height
:
28px
;
background
:
#9867f7
;
z-index
:
9
;
i
{
font-size
:
14px
;
color
:
#fff
;
margin
:
0
5px
;
cursor
:
move
;
}
}
}
}
}
}
}
}
}
}
}
}
datax-ui/src/views/dynamicform/formmaking/FormDesign.vue
0 → 100644
View file @
419077c4
<
template
>
<div
class=
"form-design-container"
>
<el-container
class=
"form-design-content"
>
<el-aside
class=
"left"
width=
"250px"
>
<template
v-if=
"formComponents.length"
>
<div
class=
"widget-cate"
>
表单组件
</div>
<draggable
tag=
"ul"
:list=
"formComponents"
v-bind=
"
{ group: { name: 'form-draggable', pull: 'clone', put: false }, sort: false, animation: 180, ghostClass: 'moving' }"
>
<li
v-for=
"(item, index) in formComponents"
:key=
"index"
@
click=
"handleListPush(item)"
>
<a>
<i
class=
"icon el-icon-star-off"
/>
<span>
{{
item
.
label
}}
</span>
</a>
</li>
</draggable>
</
template
>
<
template
v-if=
"layoutComponents.length"
>
<div
class=
"widget-cate"
>
布局组件
</div>
<draggable
tag=
"ul"
:list=
"layoutComponents"
v-bind=
"
{ group: { name: 'form-draggable', pull: 'clone', put: false }, sort: false, animation: 180, ghostClass: 'moving' }"
>
<li
v-for=
"(item, index) in layoutComponents"
:key=
"index"
@
click=
"handleListPush(item)"
>
<a>
<i
class=
"icon el-icon-star-off"
/>
<span>
{{
item
.
label
}}
</span>
</a>
</li>
</draggable>
</
template
>
</el-aside>
<el-container
class=
"widget-center-container"
direction=
"vertical"
>
<el-header
class=
"btn-bar"
style=
"height: 45px;"
>
<el-button
type=
"text"
size=
"medium"
icon=
"el-icon-view"
>
预览
</el-button>
<el-button
type=
"text"
size=
"medium"
icon=
"el-icon-refresh"
>
重置
</el-button>
<el-button
type=
"text"
size=
"medium"
icon=
"el-icon-plus"
>
保存
</el-button>
<el-button
type=
"text"
size=
"medium"
icon=
"el-icon-delete"
>
清空
</el-button>
</el-header>
<el-main>
<widget-form
:data=
"widgetData"
:select
.
sync=
"selectWidget"
/>
</el-main>
</el-container>
<el-aside
class=
"right"
>
Aside
</el-aside>
</el-container>
</div>
</template>
<
script
>
import
{
formComponents
,
layoutComponents
}
from
'./config/componentsConfig.js'
import
draggable
from
'vuedraggable'
import
WidgetForm
from
'./components/WidgetForm'
export
default
{
name
:
'FormDesign'
,
components
:
{
draggable
,
WidgetForm
},
data
()
{
return
{
formComponents
,
layoutComponents
,
widgetData
:
{
list
:
[],
config
:
{
width
:
100
,
size
:
'small'
,
labelWidth
:
100
,
labelPosition
:
'right'
,
customStyle
:
''
}
},
selectWidget
:
{}
}
},
methods
:
{
handleListPush
(
item
)
{
// 双击组件push到list
const
key
=
new
Date
().
getTime
()
item
=
{
...
item
,
key
,
model
:
item
.
type
+
'_'
+
key
}
// json深拷贝一次
const
element
=
JSON
.
parse
(
JSON
.
stringify
(
item
))
// 删除icon属性
delete
element
.
icon
this
.
widgetData
.
list
.
push
(
element
)
this
.
selectWidget
=
element
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'~@/styles/form-design.scss'
</
style
>
datax-ui/src/views/dynamicform/formmaking/components/WidgetDraggableItem.vue
0 → 100644
View file @
419077c4
<
template
>
<div>
<!-- 子表单设计模块 start -->
<template
v-if=
"element.type === 'subform'"
>
<div
class=
"subform-box"
:class=
"
{ active: element.key === selectWidget.key }"
@click.stop="handleSelectWidget(index)"
>
<div
class=
"subform-label"
>
子表单
</div>
<draggable
v-model=
"element.list"
tag=
"div"
class=
"draggable-box"
v-bind=
"
{ group: moveAllowed ? 'form-draggable' : '', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
v-for=
"(item, i) in element.list"
:key=
"item.key"
class=
"draggable-move"
:index=
"i"
:element=
"item"
:select
.
sync=
"selectWidget"
:data=
"element"
/>
</transition-group>
</draggable>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action widget-col-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag widget-col-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
</div>
</
template
>
<!-- 子表单设计模块 end -->
<!-- 标签Tabs布局 start -->
<
template
v-else-if=
"element.type === 'tabs'"
>
<div
class=
"tabs-box"
:class=
"
{ active: element.key === selectWidget.key }"
@click.stop="handleSelectWidget(index)"
>
<el-tabs
value=
"1"
:type=
"element.options.type"
:tab-position=
"element.options.tabPosition"
>
<el-tab-pane
v-for=
"(tabItem, idnex) in element.tabs"
:key=
"idnex"
:label=
"tabItem.label"
:name=
"tabItem.name"
>
<draggable
v-model=
"tabItem.list"
tag=
"div"
class=
"draggable-box"
v-bind=
"
{ group: 'form-draggable', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
v-for=
"(item, i) in tabItem.list"
:key=
"item.key"
class=
"draggable-move"
:index=
"i"
:element=
"item"
:select
.
sync=
"selectWidget"
:data=
"tabItem"
/>
</transition-group>
</draggable>
</el-tab-pane>
</el-tabs>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action widget-col-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag widget-col-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
</div>
</
template
>
<!-- 标签Tabs布局 end -->
<!-- 栅格布局 start -->
<
template
v-else-if=
"element.type === 'grid'"
>
<div
class=
"grid-box"
:class=
"
{ active: element.key === selectWidget.key }"
@click.stop="handleSelectWidget(index)"
>
<el-row
:gutter=
"element.options.gutter"
>
<el-col
v-for=
"(colItem, idnex) in element.columns"
:key=
"idnex"
:span=
"colItem.span || 0"
>
<draggable
v-model=
"colItem.list"
tag=
"div"
class=
"draggable-box"
v-bind=
"
{ group: 'form-draggable', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
v-for=
"(item, i) in colItem.list"
:key=
"item.key"
class=
"draggable-move"
:index=
"i"
:element=
"item"
:select
.
sync=
"selectWidget"
:data=
"colItem"
/>
</transition-group>
</draggable>
</el-col>
</el-row>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action widget-col-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag widget-col-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
</div>
</
template
>
<!-- 栅格布局 end -->
<!-- 卡片布局 start -->
<
template
v-else-if=
"element.type === 'card'"
>
<div
class=
"card-box"
:class=
"
{ active: element.key === selectWidget.key }"
@click.stop="handleSelectWidget(index)"
>
<el-card
class=
"box-card"
>
<div
slot=
"header"
class=
"clearfix"
>
<span>
{{
element
.
label
}}
</span>
</div>
<draggable
v-model=
"element.list"
tag=
"div"
class=
"draggable-box"
v-bind=
"
{ group: 'form-draggable', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
v-for=
"(item, i) in element.list"
:key=
"item.key"
class=
"draggable-move"
:index=
"i"
:element=
"item"
:select
.
sync=
"selectWidget"
:data=
"element"
/>
</transition-group>
</draggable>
</el-card>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action widget-col-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag widget-col-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
</div>
</
template
>
<!-- 卡片布局 end -->
<!-- 表格布局 start -->
<
template
v-else-if=
"element.type === 'table'"
>
<div
class=
"table-box"
:class=
"
{ active: element.key === selectWidget.key }"
@click.stop="handleSelectWidget(index)"
>
<table
class=
"table-layout"
:class=
"
{
bright: element.options.bright,
small: element.options.small,
bordered: element.options.bordered
}"
:style="element.options.customStyle"
>
<tr
v-for=
"(trItem, trIndex) in element.trs"
:key=
"trIndex"
>
<td
v-for=
"(tdItem, tdIndex) in trItem.tds"
:key=
"tdIndex"
:colspan=
"tdItem.colspan"
:rowspan=
"tdItem.rowspan"
>
<draggable
v-model=
"tdItem.list"
tag=
"div"
class=
"draggable-box"
v-bind=
"
{ group: 'form-draggable', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
v-for=
"(item, i) in tdItem.list"
:key=
"item.key"
class=
"draggable-move"
:index=
"i"
:element=
"item"
:select
.
sync=
"selectWidget"
:data=
"tdItem"
/>
</transition-group>
</draggable>
</td>
</tr>
</table>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action widget-col-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag widget-col-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
</div>
</
template
>
<!-- 表格布局 end -->
<
template
v-else
>
<widget-form-item
:key=
"element.key"
:index=
"index"
:element=
"element"
:select
.
sync=
"selectWidget"
:data=
"data"
/>
</
template
>
</div>
</template>
<
script
>
import
draggable
from
'vuedraggable'
import
WidgetFormItem
from
'./WidgetFormItem'
export
default
{
name
:
'WidgetDraggableItem'
,
components
:
{
draggable
,
WidgetFormItem
},
props
:
{
element
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
},
select
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
},
index
:
{
type
:
Number
,
required
:
true
},
data
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
}
},
data
()
{
return
{
moveAllowedType
:
[
'input'
,
'textarea'
,
'number'
,
'select'
,
'checkbox'
,
'radio'
,
'date'
,
'time'
,
'rate'
,
'slider'
,
'uploadFile'
,
'uploadImg'
,
'cascader'
,
'treeSelect'
,
'switch'
,
'text'
,
'html'
],
selectWidget
:
this
.
select
}
},
computed
:
{
moveAllowed
()
{
return
this
.
moveAllowedType
.
includes
(
this
.
selectWidget
.
type
)
}
},
watch
:
{
select
(
val
)
{
this
.
selectWidget
=
val
},
selectWidget
:
{
handler
(
val
)
{
this
.
$emit
(
'update:select'
,
val
)
},
deep
:
true
}
},
methods
:
{
handleSelectWidget
(
index
)
{
this
.
selectWidget
=
this
.
data
.
list
[
index
]
},
handleWidgetAdd
(
evt
)
{
// 为拖拽到容器的组件push到list
const
newIndex
=
evt
.
newIndex
const
key
=
new
Date
().
getTime
()
this
.
$set
(
this
.
data
.
list
,
newIndex
,
{
...
this
.
data
.
list
[
newIndex
],
key
,
model
:
this
.
data
.
list
[
newIndex
].
type
+
'_'
+
key
})
this
.
selectWidget
=
this
.
data
.
list
[
newIndex
]
},
handleWidgetDelete
(
index
)
{
if
(
this
.
data
.
list
.
length
-
1
===
index
)
{
if
(
index
===
0
)
{
this
.
selectWidget
=
{}
}
else
{
this
.
selectWidget
=
this
.
data
.
list
[
index
-
1
]
}
}
else
{
this
.
selectWidget
=
this
.
data
.
list
[
index
+
1
]
}
this
.
$nextTick
(()
=>
{
this
.
data
.
list
.
splice
(
index
,
1
)
})
},
handleWidgetCopy
(
index
)
{
const
key
=
new
Date
().
getTime
()
const
cloneData
=
{
...
this
.
data
.
list
[
index
],
key
,
model
:
this
.
data
.
list
[
index
].
type
+
'_'
+
key
}
// card布局处理
if
(
typeof
cloneData
.
list
!==
'undefined'
)
{
cloneData
.
list
=
[]
}
// grid布局处理
if
(
typeof
cloneData
.
columns
!==
'undefined'
)
{
cloneData
.
columns
=
JSON
.
parse
(
JSON
.
stringify
(
cloneData
.
columns
))
// 复制时,清空数据
cloneData
.
columns
.
forEach
(
item
=>
{
item
.
list
=
[]
})
}
// table布局处理
if
(
typeof
cloneData
.
trs
!==
'undefined'
)
{
cloneData
.
trs
=
JSON
.
parse
(
JSON
.
stringify
(
cloneData
.
trs
))
// 复制时,清空数据
cloneData
.
trs
.
forEach
(
item
=>
{
item
.
tds
.
forEach
(
val
=>
{
val
.
list
=
[]
})
})
}
// tabs布局处理
if
(
typeof
cloneData
.
tabs
!==
'undefined'
)
{
cloneData
.
tabs
=
JSON
.
parse
(
JSON
.
stringify
(
cloneData
.
tabs
))
// 复制时,清空数据
cloneData
.
tabs
.
forEach
(
item
=>
{
item
.
list
=
[]
})
}
this
.
data
.
list
.
splice
(
index
,
0
,
cloneData
)
this
.
$nextTick
(()
=>
{
this
.
selectWidget
=
this
.
data
.
list
[
index
+
1
]
})
}
}
}
</
script
>
<
style
scoped
>
</
style
>
datax-ui/src/views/dynamicform/formmaking/components/WidgetForm.vue
0 → 100644
View file @
419077c4
<
template
>
<div
class=
"widget-form-wrapper"
:style=
"
{ width: data.config.width + '%' }">
<el-form
:size=
"data.config.size"
label-suffix=
":"
:label-position=
"data.config.labelPosition"
:label-width=
"data.config.labelWidth + 'px'"
>
<div
v-if=
"data.list.length === 0"
class=
"form-empty"
>
从左侧拖拽或点击来添加字段
</div>
<draggable
tag=
"div"
class=
"draggable-box"
v-model=
"data.list"
v-bind=
"
{ group: 'form-draggable', ghostClass: 'moving', animation: 180, handle: '.drag-widget' }"
@add="handleWidgetAdd"
>
<transition-group
name=
"list"
tag=
"div"
class=
"draggable-list"
>
<widget-draggable-item
class=
"draggable-move"
v-for=
"(element, index) in data.list"
:key=
"element.key"
:index=
"index"
:element=
"element"
:select
.
sync=
"selectWidget"
:data=
"data"
/>
</transition-group>
</draggable>
</el-form>
</div>
</
template
>
<
script
>
import
draggable
from
'vuedraggable'
import
WidgetDraggableItem
from
'./WidgetDraggableItem'
export
default
{
name
:
'WidgetForm'
,
components
:
{
draggable
,
WidgetDraggableItem
},
props
:
{
data
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
},
select
:
{
type
:
Object
,
default
:
()
=>
({})
}
},
data
()
{
return
{
selectWidget
:
this
.
select
}
},
watch
:
{
select
(
val
)
{
this
.
selectWidget
=
val
},
selectWidget
:
{
handler
(
val
)
{
this
.
$emit
(
'update:select'
,
val
)
},
deep
:
true
}
},
methods
:
{
handleSelectWidget
(
index
)
{
this
.
selectWidget
=
this
.
data
.
list
[
index
]
},
handleWidgetAdd
(
evt
)
{
// 为拖拽到容器的组件push到list
const
newIndex
=
evt
.
newIndex
const
key
=
new
Date
().
getTime
()
this
.
$set
(
this
.
data
.
list
,
newIndex
,
{
...
this
.
data
.
list
[
newIndex
],
key
,
model
:
this
.
data
.
list
[
newIndex
].
type
+
'_'
+
key
})
// 删除icon属性
delete
this
.
data
.
list
[
newIndex
].
icon
this
.
selectWidget
=
this
.
data
.
list
[
newIndex
]
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
</
style
>
datax-ui/src/views/dynamicform/formmaking/components/WidgetFormItem.vue
0 → 100644
View file @
419077c4
<
template
>
<div
class=
"draggable-move-box"
:class=
"
{ active: selectWidget.key === element.key, 'is_hidden':element.options.hidden }"
@click.stop="handleSelectWidget(index)"
>
<div
class=
"form-item-box"
>
<el-form-item
v-if=
"element && element.key"
:class=
"
{ 'is_req': element.options.required }"
:label="element.label"
>
<template
v-if=
"element.type === 'input'"
>
<el-input
v-model=
"element.options.defaultValue"
:style=
"
{width: element.options.width}"
:disabled="element.options.disabled"
:placeholder="element.options.placeholder"
:type="element.options.type"
:clearable="element.options.clearable"
:max-length="element.options.maxLength"
/>
</
template
>
<
template
v-if=
"element.type === 'textarea'"
>
<el-input
v-model=
"element.options.defaultValue"
type=
"textarea"
:rows=
"4"
:style=
"
{width: element.options.width}"
:disabled="element.options.disabled"
:placeholder="element.options.placeholder"
:auto-size="{
minRows: element.options.minRows,
maxRows: element.options.maxRows
}"
:max-length="element.options.maxLength"
/>
</
template
>
<
template
v-if=
"element.type === 'number'"
>
<el-input-number
v-model=
"element.options.defaultValue"
:style=
"
{width: element.options.width}"
:disabled="element.options.disabled"
:controls-position="element.options.controlsPosition"
:min="element.options.min || element.options.min === 0 ? element.options.min : -Infinity"
:max="element.options.max || element.options.max === 0 ? element.options.max : Infinity"
:step="element.options.step"
:precision="element.options.precision > 50 || (!element.options.precision
&&
element.options.precision !== 0) ? null : element.options.precision"
/>
</
template
>
<
template
v-if=
"element.type == 'select'"
>
<el-select
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
:multiple=
"element.options.multiple"
:clearable=
"element.options.clearable"
:placeholder=
"element.options.placeholder"
:style=
"
{width: element.options.width}"
>
<el-option
v-for=
"(item, index) in element.options.options"
:key=
"item.value + index"
:value=
"item.value"
:label=
"item.label"
/>
</el-select>
</
template
>
<
template
v-if=
"element.type == 'radio'"
>
<el-radio-group
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
:style=
"
{width: element.options.width}"
>
<el-radio
v-for=
"(item, index) in element.options.options"
:key=
"item.value + index"
:style=
"
{display: element.options.inline ? 'inline-block' : 'block'}"
:label="item.value"
>
{{
item
.
label
}}
</el-radio>
</el-radio-group>
</
template
>
<
template
v-if=
"element.type == 'checkbox'"
>
<el-checkbox-group
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
:style=
"
{width: element.options.width}"
>
<el-checkbox
v-for=
"(item, index) in element.options.options"
:key=
"item.value + index"
:style=
"
{display: element.options.inline ? 'inline-block' : 'block'}"
:label="item.value"
>
{{
item
.
label
}}
</el-checkbox>
</el-checkbox-group>
</
template
>
<
template
v-if=
"element.type == 'date'"
>
<el-date-picker
v-model=
"element.options.defaultValue"
:type=
"element.options.type"
:placeholder=
"element.options.placeholder"
:start-placeholder=
"element.options.startPlaceholder"
:end-placeholder=
"element.options.endPlaceholder"
:readonly=
"element.options.readonly"
:disabled=
"element.options.disabled"
:editable=
"element.options.editable"
:clearable=
"element.options.clearable"
:style=
"
{width: element.options.width}"
/>
</
template
>
<
template
v-if=
"element.type == 'time'"
>
<el-time-picker
v-model=
"element.options.defaultValue"
:is-range=
"element.options.isRange"
:placeholder=
"element.options.placeholder"
:start-placeholder=
"element.options.startPlaceholder"
:end-placeholder=
"element.options.endPlaceholder"
:readonly=
"element.options.readonly"
:disabled=
"element.options.disabled"
:editable=
"element.options.editable"
:clearable=
"element.options.clearable"
:arrow-control=
"element.options.arrowControl"
:style=
"
{width: element.options.width}"
/>
</
template
>
<
template
v-if=
"element.type === 'rate'"
>
<el-rate
v-model=
"element.options.defaultValue"
:max=
"element.options.max"
:disabled=
"element.options.disabled"
:allow-half=
"element.options.allowHalf"
:show-score=
"element.options.showScore"
:style=
"
{width: element.options.width}"
/>
</
template
>
<
template
v-if=
"element.type === 'slider'"
>
<el-slider
v-model=
"element.options.defaultValue"
:min=
"element.options.min"
:max=
"element.options.max"
:disabled=
"element.options.disabled"
:step=
"element.options.step"
:show-input=
"element.options.showInput"
:style=
"
{width: element.options.width}"
/>
</
template
>
<
template
v-if=
"element.type == 'color'"
>
<el-color-picker
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
:show-alpha=
"element.options.showAlpha"
/>
</
template
>
<
template
v-if=
"element.type === 'switch'"
>
<el-switch
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
/>
</
template
>
<
template
v-if=
"element.type == 'cascader'"
>
<el-cascader
v-model=
"element.options.defaultValue"
:disabled=
"element.options.disabled"
:clearable=
"element.options.clearable"
:placeholder=
"element.options.placeholder"
:style=
"
{width: element.options.width}"
:options="element.options.options"
:props="element.options.props"
/>
</
template
>
<
template
v-if=
"element.type == 'editor'"
>
<vue-editor
v-model=
"element.options.defaultValue"
:style=
"
{width: element.options.width}"
>
</vue-editor>
</
template
>
<
template
v-if=
"element.type === 'alert'"
>
<el-alert
:title=
"element.options.title"
:description=
"element.options.description"
:type=
"element.options.type"
:effect=
"element.options.effect"
:show-icon=
"element.options.showIcon"
:closable=
"element.options.closable"
:center=
"element.options.center"
/>
</
template
>
<
template
v-if=
"element.type === 'text'"
>
<div
:style=
"
{ textAlign: element.options.textAlign }">
<label
v-text=
"element.options.defaultValue"
/>
</div>
</
template
>
<
template
v-if=
"element.type === 'html'"
>
<div
v-html=
"element.options.defaultValue"
/>
</
template
>
<
template
v-if=
"element.type === 'divider'"
>
<el-divider
:content-position=
"element.options.orientation"
>
{{
element
.
label
}}
</el-divider>
</
template
>
</el-form-item>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-action"
>
<i
class=
"el-icon-copy-document"
@
click
.
stop=
"handleWidgetCopy(index)"
/>
<i
class=
"el-icon-delete"
@
click
.
stop=
"handleWidgetDelete(index)"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-drag"
>
<i
class=
"el-icon-rank drag-widget"
/>
</div>
<div
v-if=
"selectWidget.key === element.key"
class=
"widget-view-model"
>
<span>
{{ selectWidget.model }}
</span>
</div>
</div>
</template>
<
script
>
import
{
VueEditor
}
from
'vue2-editor'
export
default
{
name
:
'WidgetFormItem'
,
components
:
{
VueEditor
},
props
:
{
element
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
},
select
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
},
index
:
{
type
:
Number
,
required
:
true
},
data
:
{
type
:
Object
,
required
:
true
,
default
:
()
=>
({})
}
},
data
()
{
return
{
selectWidget
:
this
.
select
}
},
watch
:
{
select
(
val
)
{
this
.
selectWidget
=
val
},
selectWidget
:
{
handler
(
val
)
{
this
.
$emit
(
'update:select'
,
val
)
},
deep
:
true
}
},
methods
:
{
handleSelectWidget
(
index
)
{
this
.
selectWidget
=
this
.
data
.
list
[
index
]
},
handleWidgetDelete
(
index
)
{
if
(
this
.
data
.
list
.
length
-
1
===
index
)
{
if
(
index
===
0
)
{
this
.
selectWidget
=
{}
}
else
{
this
.
selectWidget
=
this
.
data
.
list
[
index
-
1
]
}
}
else
{
this
.
selectWidget
=
this
.
data
.
list
[
index
+
1
]
}
this
.
$nextTick
(()
=>
{
this
.
data
.
list
.
splice
(
index
,
1
)
})
},
handleWidgetCopy
(
index
)
{
const
key
=
new
Date
().
getTime
()
const
cloneData
=
{
...
this
.
data
.
list
[
index
],
key
,
model
:
this
.
data
.
list
[
index
].
type
+
'_'
+
key
}
this
.
data
.
list
.
splice
(
index
,
0
,
cloneData
)
this
.
$nextTick
(()
=>
{
this
.
selectWidget
=
this
.
data
.
list
[
index
+
1
]
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
</
style
>
datax-ui/src/views/dynamicform/formmaking/config/componentsConfig.js
0 → 100644
View file @
419077c4
// 表单组件
export
const
formComponents
=
[
{
type
:
'input'
,
// 表单类型
label
:
'输入框'
,
// 标题文字
icon
:
'icon-input'
,
// 图标
options
:
{
type
:
'text'
,
// 文本或密码,text或者password
width
:
'100%'
,
// 宽度
defaultValue
:
''
,
// 默认值
placeholder
:
''
,
// 没有输入时,提示文字
maxLength
:
null
,
// 最大长度
clearable
:
false
,
// 是否可清除,false否,true是
hidden
:
false
,
// 是否隐藏,false显示,true隐藏
disabled
:
false
// 是否禁用,false不禁用,true禁用
},
model
:
''
,
// 字段标识
key
:
''
,
rules
:
[
// 验证规则
{
required
:
false
,
// 必须填写
message
:
'必填项'
}
]
},
{
type
:
'textarea'
,
label
:
'文本框'
,
icon
:
'icon-edit'
,
options
:
{
width
:
'100%'
,
defaultValue
:
''
,
placeholder
:
''
,
minRows
:
4
,
// 最小行数
maxRows
:
6
,
// 最大行数
maxLength
:
null
,
hidden
:
false
,
disabled
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'number'
,
label
:
'数字输入框'
,
icon
:
'icon-number'
,
options
:
{
width
:
'100%'
,
defaultValue
:
0
,
placeholder
:
''
,
min
:
null
,
max
:
null
,
precision
:
null
,
step
:
1
,
hidden
:
false
,
disabled
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'select'
,
label
:
'下拉选择器'
,
icon
:
'icon-xiala'
,
options
:
{
width
:
'100%'
,
defaultValue
:
''
,
multiple
:
false
,
disabled
:
false
,
clearable
:
false
,
hidden
:
false
,
placeholder
:
''
,
dynamic
:
false
,
dynamicKey
:
''
,
dynamicFunc
:
''
,
options
:
[
{
value
:
'1'
,
label
:
'下拉框1'
},
{
value
:
'2'
,
label
:
'下拉框2'
}
]
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'checkbox'
,
label
:
'多选框'
,
icon
:
'icon-duoxuan1'
,
options
:
{
disabled
:
false
,
hidden
:
false
,
defaultValue
:
[],
inline
:
false
,
dynamic
:
false
,
dynamicKey
:
''
,
dynamicFunc
:
''
,
options
:
[
{
value
:
'1'
,
label
:
'选项1'
},
{
value
:
'2'
,
label
:
'选项2'
},
{
value
:
'3'
,
label
:
'选项3'
}
]
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'radio'
,
label
:
'单选框'
,
icon
:
'icon-danxuan-cuxiantiao'
,
options
:
{
disabled
:
false
,
hidden
:
false
,
defaultValue
:
''
,
inline
:
false
,
dynamic
:
false
,
dynamicKey
:
''
,
dynamicFunc
:
''
,
options
:
[
{
value
:
'1'
,
label
:
'选项1'
},
{
value
:
'2'
,
label
:
'选项2'
},
{
value
:
'3'
,
label
:
'选项3'
}
]
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'date'
,
label
:
'日期选择框'
,
icon
:
'icon-calendar'
,
options
:
{
width
:
'100%'
,
defaultValue
:
''
,
placeholder
:
''
,
hidden
:
false
,
readonly
:
false
,
disabled
:
false
,
editable
:
true
,
clearable
:
true
,
startPlaceholder
:
''
,
endPlaceholder
:
''
,
type
:
'date'
,
format
:
'yyyy-MM-dd'
,
timestamp
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'time'
,
label
:
'时间选择框'
,
icon
:
'icon-time'
,
options
:
{
width
:
'100%'
,
defaultValue
:
''
,
placeholder
:
''
,
hidden
:
false
,
readonly
:
false
,
disabled
:
false
,
editable
:
true
,
clearable
:
true
,
isRange
:
false
,
startPlaceholder
:
''
,
endPlaceholder
:
''
,
arrowControl
:
true
,
format
:
'HH:mm:ss'
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'rate'
,
label
:
'评分'
,
icon
:
'icon-pingfen_moren'
,
options
:
{
defaultValue
:
0
,
max
:
5
,
disabled
:
false
,
hidden
:
false
,
allowHalf
:
false
,
showScore
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'slider'
,
label
:
'滑动输入条'
,
icon
:
'icon-menu'
,
options
:
{
width
:
'100%'
,
defaultValue
:
0
,
disabled
:
false
,
hidden
:
false
,
min
:
0
,
max
:
100
,
step
:
1
,
showInput
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'color'
,
label
:
'颜色选择器'
,
icon
:
'icon-pingfen_moren'
,
options
:
{
defaultValue
:
''
,
disabled
:
false
,
hidden
:
false
,
showAlpha
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
// {
// type: 'uploadFile',
// label: '上传文件',
// icon: 'icon-upload',
// options: {
// defaultValue: [],
// disabled: false,
// hidden: false,
// multiple: false,
// width: '100%',
// limit: 3,
// data: '{}',
// fileName: 'file',
// headers: {},
// action: 'http://cdn.kcz66.com/uploadFile.txt',
// placeholder: '上传'
// },
// model: '',
// key: '',
// rules: [
// {
// required: false,
// message: '必填项'
// }
// ]
// },
// {
// type: 'uploadImg',
// label: '上传图片',
// icon: 'icon-image',
// options: {
// defaultValue: [],
// hidden: false,
// disabled: false,
// multiple: false,
// width: '100%',
// data: '{}',
// limit: 3,
// placeholder: '上传',
// fileName: 'image',
// headers: {},
// action: 'http://cdn.kcz66.com/upload-img.txt',
// listType: 'picture-card'
// },
// model: '',
// key: '',
// rules: [
// {
// required: false,
// message: '必填项'
// }
// ]
// },
{
type
:
'cascader'
,
label
:
'级联选择器'
,
icon
:
'icon-guanlian'
,
options
:
{
disabled
:
false
,
hidden
:
false
,
defaultValue
:
[],
placeholder
:
''
,
width
:
'100%'
,
clearable
:
false
,
dynamic
:
false
,
dynamicKey
:
''
,
dynamicFunc
:
''
,
options
:
[
{
value
:
'1'
,
label
:
'选项1'
,
children
:
[
{
value
:
'11'
,
label
:
'选项11'
}
]
},
{
value
:
'2'
,
label
:
'选项2'
,
children
:
[
{
value
:
'22'
,
label
:
'选项22'
}
]
}
],
props
:
{
value
:
'value'
,
label
:
'label'
,
children
:
'children'
}
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'subform'
,
label
:
'子表单'
,
icon
:
'icon-biaoge'
,
list
:
[],
options
:
{
scrollY
:
0
,
disabled
:
false
,
hidden
:
false
,
showLabel
:
false
,
hideSequence
:
false
,
width
:
'100%'
},
model
:
''
,
key
:
''
},
{
type
:
'editor'
,
label
:
'富文本'
,
icon
:
'icon-LC_icon_edit_line_1'
,
options
:
{
height
:
300
,
placeholder
:
''
,
defaultValue
:
''
,
hidden
:
false
,
disabled
:
false
,
width
:
'100%'
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'switch'
,
label
:
'开关'
,
icon
:
'icon-kaiguan3'
,
options
:
{
defaultValue
:
false
,
hidden
:
false
,
disabled
:
false
},
model
:
''
,
key
:
''
,
rules
:
[
{
required
:
false
,
message
:
'必填项'
}
]
},
{
type
:
'alert'
,
label
:
'警告提示'
,
icon
:
'icon-zu'
,
options
:
{
type
:
'success'
,
title
:
'提示的文案'
,
description
:
''
,
effect
:
''
,
hidden
:
false
,
showIcon
:
false
,
closable
:
false
,
center
:
false
},
model
:
''
,
key
:
''
},
{
type
:
'text'
,
label
:
'文字'
,
icon
:
'icon-zihao'
,
options
:
{
hidden
:
false
,
textAlign
:
'left'
,
defaultValue
:
'This is a text'
},
model
:
''
,
key
:
''
},
{
type
:
'html'
,
label
:
'HTML'
,
icon
:
'icon-ai-code'
,
options
:
{
hidden
:
false
,
defaultValue
:
'<strong>This is a HTML</strong>'
},
model
:
''
,
key
:
''
}
]
// 布局组件
export
const
layoutComponents
=
[
{
type
:
'divider'
,
label
:
'分割线'
,
icon
:
'icon-fengexian'
,
options
:
{
hidden
:
false
,
orientation
:
'left'
},
key
:
''
,
model
:
''
},
{
type
:
'grid'
,
label
:
'栅格布局'
,
icon
:
'icon-zhage'
,
columns
:
[
{
span
:
12
,
list
:
[]
},
{
span
:
12
,
list
:
[]
}
],
options
:
{
gutter
:
0
},
key
:
''
,
model
:
''
},
{
type
:
'table'
,
label
:
'表格布局'
,
icon
:
'icon-biaoge'
,
trs
:
[
{
tds
:
[
{
colspan
:
1
,
rowspan
:
1
,
list
:
[]
},
{
colspan
:
1
,
rowspan
:
1
,
list
:
[]
}
]
},
{
tds
:
[
{
colspan
:
1
,
rowspan
:
1
,
list
:
[]
},
{
colspan
:
1
,
rowspan
:
1
,
list
:
[]
}
]
}
],
options
:
{
width
:
'100%'
,
bordered
:
true
,
bright
:
false
,
small
:
true
,
customStyle
:
''
},
key
:
''
,
model
:
''
},
{
type
:
'tabs'
,
label
:
'标签页布局'
,
icon
:
'icon-tabs'
,
options
:
{
type
:
'border-card'
,
tabPosition
:
'top'
},
tabs
:
[
{
name
:
'1'
,
label
:
'选项1'
,
list
:
[]
},
{
name
:
'2'
,
label
:
'选项2'
,
list
:
[]
}
],
key
:
''
,
model
:
''
},
{
type
:
'card'
,
label
:
'卡片布局'
,
icon
:
'icon-qiapian'
,
list
:
[],
key
:
''
,
model
:
''
}
]
datax-ui/src/views/dynamicform/index.vue
0 → 100644
View file @
419077c4
<
template
>
<div
class=
"app-container"
>
DynamicForm
</div>
</
template
>
<
script
>
export
default
{
name
:
'DynamicForm'
}
</
script
>
<
style
lang=
"scss"
scoped
>
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment