vue-form-craft 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -10
- package/src/components/FormPlus/FormDesign/Actions.vue +97 -0
- package/src/components/FormPlus/FormDesign/Canvas/CanvasGroup.vue +81 -0
- package/src/components/FormPlus/FormDesign/Canvas/CanvasRender.vue +101 -0
- package/src/components/FormPlus/FormDesign/Canvas/index.vue +119 -0
- package/src/components/FormPlus/FormDesign/Current/AttrEdit.vue +44 -0
- package/src/components/FormPlus/FormDesign/Current/FormEdit.vue +33 -0
- package/src/components/FormPlus/FormDesign/Current/formOptions.js +43 -0
- package/src/components/FormPlus/FormDesign/Current/index.vue +17 -0
- package/src/components/FormPlus/FormDesign/Menus/IconRender.vue +28 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/card.js +6 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/formList.js +28 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/index.js +10 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/input.js +47 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/inputNumber.js +43 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/itemGroup.js +3 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/password.js +46 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/radio.js +120 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/select.js +175 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/switch.js +31 -0
- package/src/components/FormPlus/FormDesign/Menus/attrs/textarea.js +65 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/card.vue +33 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/formList.vue +18 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/input.vue +19 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/inputNumber.vue +21 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/itemGroup.vue +17 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/password.vue +24 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/radio.vue +23 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/select.vue +22 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/switch.vue +21 -0
- package/src/components/FormPlus/FormDesign/Menus/icons/textarea.vue +28 -0
- package/src/components/FormPlus/FormDesign/Menus/index.vue +73 -0
- package/src/components/FormPlus/FormDesign/Menus/menus.js +67 -0
- package/src/components/FormPlus/FormDesign/index.vue +128 -0
- package/src/components/FormPlus/components/FormGroup.vue +70 -0
- package/src/components/FormPlus/components/FormItem.vue +137 -0
- package/src/components/FormPlus/components/FormRender.vue +41 -0
- package/src/components/FormPlus/components/SchemaForm.vue +88 -0
- package/src/components/FormPlus/components/basic/NumberInput.vue +42 -0
- package/src/components/FormPlus/components/basic/RadioPlus.vue +162 -0
- package/src/components/FormPlus/components/basic/SelectPlus.vue +199 -0
- package/src/components/FormPlus/components/group/FormList.vue +195 -0
- package/src/components/FormPlus/components/group/ItemGroup.vue +32 -0
- package/src/components/FormPlus/components/index.js +9 -0
- package/src/components/FormPlus/index.js +13 -0
- package/src/components/FormPlus/utils.js +120 -0
- package/dist/card-wn9zrEz2.js +0 -63
- package/dist/favicon.ico +0 -0
- package/dist/formList-Dk5xZstV.js +0 -30
- package/dist/index-dQCVeu7G.js +0 -38464
- package/dist/input-DEmT1x9i.js +0 -31
- package/dist/inputNumber-Z63pmgOq.js +0 -39
- package/dist/itemGroup-xR-JI8gC.js +0 -29
- package/dist/password-gJVmLHdQ.js +0 -42
- package/dist/radio-tgpGlU0X.js +0 -41
- package/dist/select-SvqpBOxq.js +0 -40
- package/dist/style.css +0 -6
- package/dist/switch-auAsEfGN.js +0 -39
- package/dist/textarea-vmdhun99.js +0 -52
- package/dist/vue-form-craft.es.js +0 -6
- package/dist/vue-form-craft.umd.js +0 -1447
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-form-craft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -34,14 +34,7 @@
|
|
|
34
34
|
"scp2": "^0.5.0"
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
|
-
"
|
|
37
|
+
"src/components/FormPlus"
|
|
38
38
|
],
|
|
39
|
-
"main": "./
|
|
40
|
-
"module": "./dist/vue-form-craft.es.js",
|
|
41
|
-
"exports": {
|
|
42
|
-
".": {
|
|
43
|
-
"import": "./dist/vue-form-craft.es.js",
|
|
44
|
-
"require": "./dist/vue-form-craft.umd.js"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
39
|
+
"main": "./src/components/FormPlus/index.js"
|
|
47
40
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="formDesign-actions">
|
|
3
|
+
<el-button @click="handlePreviewExec">预览脚本</el-button>
|
|
4
|
+
<el-button @click="handlePreviewForm">预览表单</el-button>
|
|
5
|
+
|
|
6
|
+
<el-dialog
|
|
7
|
+
v-model="execVisible"
|
|
8
|
+
title="预览脚本"
|
|
9
|
+
width="70%"
|
|
10
|
+
class="dialog"
|
|
11
|
+
center
|
|
12
|
+
destroy-on-close
|
|
13
|
+
>
|
|
14
|
+
<json-editor-vue
|
|
15
|
+
class="editor"
|
|
16
|
+
v-model="json"
|
|
17
|
+
currentMode="code"
|
|
18
|
+
:modeList="['text', 'view', 'tree', 'code', 'form']"
|
|
19
|
+
:options="{ search: true, history: true }"
|
|
20
|
+
language="zh"
|
|
21
|
+
@blur="onBlur"
|
|
22
|
+
/>
|
|
23
|
+
</el-dialog>
|
|
24
|
+
|
|
25
|
+
<el-dialog
|
|
26
|
+
v-model="formVisible"
|
|
27
|
+
title="预览表单"
|
|
28
|
+
width="70%"
|
|
29
|
+
class="dialog"
|
|
30
|
+
destroy-on-close
|
|
31
|
+
center
|
|
32
|
+
>
|
|
33
|
+
<schema-form v-model="form" :schema="schema" ref="formRef" />
|
|
34
|
+
<div>
|
|
35
|
+
<el-button @click="handlePush">模拟提交</el-button>
|
|
36
|
+
</div>
|
|
37
|
+
</el-dialog>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup lang="jsx">
|
|
42
|
+
import { ref, computed, inject } from 'vue'
|
|
43
|
+
import JsonEditorVue from 'json-editor-vue3'
|
|
44
|
+
import { ElMessageBox } from 'element-plus'
|
|
45
|
+
import { SchemaForm } from '../components'
|
|
46
|
+
import { changeItems } from '../utils'
|
|
47
|
+
|
|
48
|
+
const schema = inject('$schema')
|
|
49
|
+
|
|
50
|
+
const json = computed({
|
|
51
|
+
get() {
|
|
52
|
+
return schema
|
|
53
|
+
},
|
|
54
|
+
set(value) {
|
|
55
|
+
Object.assign(schema, value)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const formRef = ref(null)
|
|
60
|
+
|
|
61
|
+
const form = ref({})
|
|
62
|
+
|
|
63
|
+
const execVisible = ref(false)
|
|
64
|
+
|
|
65
|
+
const formVisible = ref(false)
|
|
66
|
+
|
|
67
|
+
const handlePreviewExec = () => {
|
|
68
|
+
execVisible.value = true
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const handlePreviewForm = () => {
|
|
72
|
+
form.value = {}
|
|
73
|
+
formVisible.value = true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const onBlur = async (editor) => {
|
|
77
|
+
const res = await editor.validate()
|
|
78
|
+
if (res.length) {
|
|
79
|
+
let parse = editor.getText()
|
|
80
|
+
parse = new Function('return ' + parse)()
|
|
81
|
+
parse.items = changeItems(parse.items)
|
|
82
|
+
json.value = parse
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const handlePush = async () => {
|
|
87
|
+
await formRef.value.submit()
|
|
88
|
+
ElMessageBox.alert(JSON.stringify(form.value), '模拟提交')
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style>
|
|
93
|
+
.formDesign-actions {
|
|
94
|
+
padding: 10px;
|
|
95
|
+
text-align: right;
|
|
96
|
+
}
|
|
97
|
+
</style>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="CanvasGroup">
|
|
3
|
+
<el-card v-if="component === 'card'" :header="label">
|
|
4
|
+
<draggable
|
|
5
|
+
:list="children"
|
|
6
|
+
group="form"
|
|
7
|
+
itemKey="name"
|
|
8
|
+
chosenClass="active"
|
|
9
|
+
ghost-class="ghost"
|
|
10
|
+
class="childContainer"
|
|
11
|
+
@add="handleAdd"
|
|
12
|
+
>
|
|
13
|
+
<template #item="{ element: child, index }">
|
|
14
|
+
<CanvasRender :element="child" :index="index" />
|
|
15
|
+
</template>
|
|
16
|
+
</draggable>
|
|
17
|
+
</el-card>
|
|
18
|
+
|
|
19
|
+
<div v-if="['formList', 'itemGroup'].includes(component)" class="default">
|
|
20
|
+
<div class="title">
|
|
21
|
+
【{{ componentNames[component] }}】 {{ label }} {{ name }}
|
|
22
|
+
</div>
|
|
23
|
+
<draggable
|
|
24
|
+
:list="children"
|
|
25
|
+
group="form"
|
|
26
|
+
itemKey="name"
|
|
27
|
+
chosenClass="active"
|
|
28
|
+
ghost-class="ghost"
|
|
29
|
+
class="childContainer"
|
|
30
|
+
@add="handleAdd"
|
|
31
|
+
>
|
|
32
|
+
<template #item="{ element: child, index }">
|
|
33
|
+
<CanvasRender :element="child" :index="index" />
|
|
34
|
+
</template>
|
|
35
|
+
</draggable>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup lang="jsx">
|
|
41
|
+
import { defineProps, inject } from "vue";
|
|
42
|
+
import draggable from "vuedraggable";
|
|
43
|
+
import CanvasRender from "./CanvasRender.vue";
|
|
44
|
+
import { componentNames } from "../../utils";
|
|
45
|
+
|
|
46
|
+
defineProps({
|
|
47
|
+
label: String,
|
|
48
|
+
name: String,
|
|
49
|
+
component: String,
|
|
50
|
+
required: Boolean,
|
|
51
|
+
modelValue: null,
|
|
52
|
+
initialValue: null,
|
|
53
|
+
children: Array,
|
|
54
|
+
componentName: String,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const handleAdd = inject("handleAdd");
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<style lang="less">
|
|
61
|
+
.childContainer {
|
|
62
|
+
min-height: 150px;
|
|
63
|
+
}
|
|
64
|
+
.CanvasGroup {
|
|
65
|
+
margin-bottom: 10px;
|
|
66
|
+
.default {
|
|
67
|
+
border: 2px dashed var(--el-color-primary);
|
|
68
|
+
margin: 10px;
|
|
69
|
+
position: relative;
|
|
70
|
+
.title {
|
|
71
|
+
position: absolute;
|
|
72
|
+
left: 0;
|
|
73
|
+
top: -20px;
|
|
74
|
+
padding: 1px 5px;
|
|
75
|
+
background-color: var(--el-color-primary);
|
|
76
|
+
font-size: 12px;
|
|
77
|
+
color: #fff;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="canvasItemClass"
|
|
4
|
+
@click.stop="handleSelect(element)"
|
|
5
|
+
@mousemove.stop="handleHoverEnter"
|
|
6
|
+
@mouseleave.stop="handleHoverLeave"
|
|
7
|
+
>
|
|
8
|
+
<div class="actions-left-top" v-if="element.onlyId === current.onlyId">
|
|
9
|
+
<el-button class="canvas-move" :icon="Pointer" size="small" type="primary"></el-button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="actions-right-bottom" v-if="element.onlyId === current.onlyId">
|
|
12
|
+
<el-button
|
|
13
|
+
:icon="Delete"
|
|
14
|
+
size="small"
|
|
15
|
+
type="primary"
|
|
16
|
+
@click.stop="handleDelete(element)"
|
|
17
|
+
></el-button>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<canvas-group v-if="element.children" v-bind="element" :hidden="false" />
|
|
21
|
+
|
|
22
|
+
<form-item v-else v-bind="element" :props="checkProps(element.props)" class="form-item-btn" />
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup lang="jsx">
|
|
27
|
+
import { defineProps, inject, computed } from 'vue'
|
|
28
|
+
import { omit } from 'lodash'
|
|
29
|
+
import { Delete, Pointer } from '@element-plus/icons-vue'
|
|
30
|
+
import CanvasGroup from './CanvasGroup.vue'
|
|
31
|
+
import { FormItem } from '../../components'
|
|
32
|
+
|
|
33
|
+
const props = defineProps({
|
|
34
|
+
element: Object
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const current = inject('$current')
|
|
38
|
+
|
|
39
|
+
const handleSelect = inject('handleSelect')
|
|
40
|
+
|
|
41
|
+
const handleDelete = inject('handleDelete')
|
|
42
|
+
|
|
43
|
+
const hoverId = inject('hoverId')
|
|
44
|
+
|
|
45
|
+
const canvasItemClass = computed(() => ({
|
|
46
|
+
'canvas-item': true,
|
|
47
|
+
active: props.element.onlyId === current.value.onlyId,
|
|
48
|
+
hover: props.element.onlyId === hoverId.value
|
|
49
|
+
}))
|
|
50
|
+
|
|
51
|
+
const handleHoverEnter = () => {
|
|
52
|
+
hoverId.value = props.element.onlyId
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const handleHoverLeave = () => {
|
|
56
|
+
hoverId.value = ''
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const checkProps = (props) => {
|
|
60
|
+
return omit(props, ['multiple', 'autoSelectedFirst'])
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<style lang="less">
|
|
65
|
+
.canvas-item {
|
|
66
|
+
border: 2px solid transparent;
|
|
67
|
+
margin-bottom: 5px;
|
|
68
|
+
padding: 10px;
|
|
69
|
+
position: relative;
|
|
70
|
+
|
|
71
|
+
#form-item {
|
|
72
|
+
margin-bottom: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.actions-left-top {
|
|
76
|
+
position: absolute;
|
|
77
|
+
left: 0;
|
|
78
|
+
top: 0;
|
|
79
|
+
z-index: 20;
|
|
80
|
+
background-color: var(--el-color-primary);
|
|
81
|
+
}
|
|
82
|
+
.actions-right-bottom {
|
|
83
|
+
position: absolute;
|
|
84
|
+
right: 0;
|
|
85
|
+
bottom: 0;
|
|
86
|
+
z-index: 20;
|
|
87
|
+
background-color: var(--el-color-primary);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.hover {
|
|
92
|
+
border: 2px solid var(--el-color-primary-light-5);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.active {
|
|
96
|
+
border: 2px solid var(--el-color-primary) !important;
|
|
97
|
+
&:hover {
|
|
98
|
+
border: 2px solid var(--el-color-primary) !important;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-form
|
|
3
|
+
class="canvas"
|
|
4
|
+
:style="`max-width: ${schema.formWidth}`"
|
|
5
|
+
:label-position="schema.labelAlign"
|
|
6
|
+
:size="schema.size"
|
|
7
|
+
>
|
|
8
|
+
<div class="tip" v-if="!list.length">
|
|
9
|
+
<div class="ico">
|
|
10
|
+
<el-icon>
|
|
11
|
+
<Plus />
|
|
12
|
+
</el-icon>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="text">请从左侧拖拽字段来组成表单</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<draggable
|
|
18
|
+
style="height: 100%"
|
|
19
|
+
:list="list"
|
|
20
|
+
:group="{ name: 'form', pull: true, put: true }"
|
|
21
|
+
itemKey="name"
|
|
22
|
+
chooseClass="choose"
|
|
23
|
+
ghost-class="ghost"
|
|
24
|
+
@add="handleAdd"
|
|
25
|
+
drag-class="drag"
|
|
26
|
+
fallback-class="fallback"
|
|
27
|
+
handle=".canvas-move"
|
|
28
|
+
>
|
|
29
|
+
<template #item="{ element }">
|
|
30
|
+
<CanvasRender :element="element" />
|
|
31
|
+
</template>
|
|
32
|
+
</draggable>
|
|
33
|
+
</el-form>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="jsx">
|
|
37
|
+
import { computed, provide, inject, ref } from 'vue'
|
|
38
|
+
import draggable from 'vuedraggable'
|
|
39
|
+
import { Plus } from '@element-plus/icons-vue'
|
|
40
|
+
import { changeItems } from '../../utils'
|
|
41
|
+
import CanvasRender from './CanvasRender.vue'
|
|
42
|
+
|
|
43
|
+
const schema = inject('$schema')
|
|
44
|
+
|
|
45
|
+
const current = inject('$current')
|
|
46
|
+
|
|
47
|
+
const hoverId = ref('')
|
|
48
|
+
|
|
49
|
+
provide('hoverId', hoverId)
|
|
50
|
+
|
|
51
|
+
const list = computed({
|
|
52
|
+
get() {
|
|
53
|
+
return schema.items
|
|
54
|
+
},
|
|
55
|
+
set(value) {
|
|
56
|
+
Object.assign(schema, { items: value })
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const handleAdd = () => {
|
|
61
|
+
list.value = changeItems(list.value)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const filterId = (items, elementId) => {
|
|
65
|
+
const data = items.filter((item) => {
|
|
66
|
+
return item.onlyId !== elementId
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
return data.map((item) => {
|
|
70
|
+
if (item.children) {
|
|
71
|
+
return {
|
|
72
|
+
...item,
|
|
73
|
+
children: filterId(item.children, elementId)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return item
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const handleDelete = (element) => {
|
|
81
|
+
list.value = filterId(list.value, element.onlyId)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const handleSelect = (element) => {
|
|
85
|
+
current.value = element
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
provide('handleAdd', handleAdd)
|
|
89
|
+
provide('handleSelect', handleSelect)
|
|
90
|
+
provide('handleDelete', handleDelete)
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<style lang="less">
|
|
94
|
+
.canvas {
|
|
95
|
+
flex: 1;
|
|
96
|
+
padding: 20px;
|
|
97
|
+
border: 1px dashed #999;
|
|
98
|
+
position: relative;
|
|
99
|
+
.tip {
|
|
100
|
+
color: #999;
|
|
101
|
+
font-size: 18px;
|
|
102
|
+
width: 100%;
|
|
103
|
+
text-align: center;
|
|
104
|
+
position: absolute;
|
|
105
|
+
left: 0;
|
|
106
|
+
top: 40%;
|
|
107
|
+
transform: translateY(-50%);
|
|
108
|
+
.ico {
|
|
109
|
+
font-size: 30px;
|
|
110
|
+
margin-bottom: 15px;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.ghost {
|
|
115
|
+
border-top: 2px solid var(--el-color-primary);
|
|
116
|
+
list-style: none;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="attrForm">
|
|
3
|
+
<schema-form v-model="current" :schema="attrs[current.component]"></schema-form>
|
|
4
|
+
|
|
5
|
+
<div>
|
|
6
|
+
<el-button @click="handleEdit">编辑配置文本</el-button>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<el-drawer destroy-on-close v-model="editVisible">
|
|
10
|
+
<json-editor-vue
|
|
11
|
+
class="editor"
|
|
12
|
+
v-model="current"
|
|
13
|
+
currentMode="code"
|
|
14
|
+
:modeList="['text', 'view', 'tree', 'code', 'form']"
|
|
15
|
+
:options="{ search: true, history: true }"
|
|
16
|
+
language="zh"
|
|
17
|
+
/>
|
|
18
|
+
</el-drawer>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script setup lang="jsx">
|
|
23
|
+
import { inject, ref } from 'vue'
|
|
24
|
+
import JsonEditorVue from 'json-editor-vue3'
|
|
25
|
+
import * as attrs from '../Menus/attrs'
|
|
26
|
+
import { SchemaForm } from '../../components'
|
|
27
|
+
|
|
28
|
+
const current = inject('$current')
|
|
29
|
+
|
|
30
|
+
const editVisible = ref(false)
|
|
31
|
+
|
|
32
|
+
const handleEdit = () => {
|
|
33
|
+
editVisible.value = true
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<style scoped lang="less">
|
|
38
|
+
.attrForm {
|
|
39
|
+
h3 {
|
|
40
|
+
margin-bottom: 10px;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
44
|
+
../Menus/attrs
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="attrForm">
|
|
3
|
+
<schema-form v-model="form" :schema="formOptions"></schema-form>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="jsx">
|
|
8
|
+
import { computed, inject } from 'vue'
|
|
9
|
+
import { SchemaForm } from '../../components'
|
|
10
|
+
import formOptions from './formOptions'
|
|
11
|
+
|
|
12
|
+
const schema = inject('$schema')
|
|
13
|
+
|
|
14
|
+
//修改schema除了items的其他属性
|
|
15
|
+
const form = computed({
|
|
16
|
+
get() {
|
|
17
|
+
return schema
|
|
18
|
+
},
|
|
19
|
+
set(value) {
|
|
20
|
+
Object.assign(schema, value)
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<style scoped lang="less">
|
|
26
|
+
.attrForm {
|
|
27
|
+
height: 100%;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
h3 {
|
|
30
|
+
margin-bottom: 10px;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
items: [
|
|
3
|
+
{
|
|
4
|
+
label: "label宽度",
|
|
5
|
+
component: "inputNumber",
|
|
6
|
+
name: "labelWidth",
|
|
7
|
+
props: {
|
|
8
|
+
min: 60,
|
|
9
|
+
unit: "px",
|
|
10
|
+
step: 10,
|
|
11
|
+
},
|
|
12
|
+
initialValue: 150,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
label: "label对齐方式",
|
|
16
|
+
component: "radio",
|
|
17
|
+
name: "labelAlign",
|
|
18
|
+
props: {
|
|
19
|
+
mode: "static",
|
|
20
|
+
options: [
|
|
21
|
+
{ label: "左对齐", value: "left" },
|
|
22
|
+
{ label: "居上", value: "top" },
|
|
23
|
+
{ label: "右对齐", value: "right" },
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
initialValue: "right",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "表单组件尺寸",
|
|
30
|
+
component: "radio",
|
|
31
|
+
name: "size",
|
|
32
|
+
props: {
|
|
33
|
+
mode: "static",
|
|
34
|
+
options: [
|
|
35
|
+
{ label: "默认", value: "default" },
|
|
36
|
+
{ label: "较小", value: "small" },
|
|
37
|
+
{ label: "较大", value: "large" },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
initialValue: "default",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-tabs>
|
|
3
|
+
<el-tab-pane label="字段配置">
|
|
4
|
+
<AttrEdit />
|
|
5
|
+
</el-tab-pane>
|
|
6
|
+
<el-tab-pane label="表单配置">
|
|
7
|
+
<FormEdit />
|
|
8
|
+
</el-tab-pane>
|
|
9
|
+
</el-tabs>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
import AttrEdit from "./AttrEdit.vue";
|
|
14
|
+
import FormEdit from "./FormEdit.vue";
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<style></style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component class="svg-icon" :is="icon" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="jsx">
|
|
6
|
+
import { defineProps, ref } from 'vue'
|
|
7
|
+
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
name: String
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const icon = ref(null)
|
|
13
|
+
|
|
14
|
+
import(`./icons/${props.name}.vue`).then((module) => {
|
|
15
|
+
icon.value = module.default
|
|
16
|
+
})
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.svg-icon {
|
|
21
|
+
display: inline-block;
|
|
22
|
+
width: 1em;
|
|
23
|
+
height: 1em;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
vertical-align: -0.15em;
|
|
26
|
+
fill: currentColor;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
items: [
|
|
3
|
+
{ label: '字段label', component: 'input', name: 'label' },
|
|
4
|
+
{ label: '字段标识', component: 'input', name: 'name' },
|
|
5
|
+
{ label: '是否必填', component: 'switch', name: 'required' },
|
|
6
|
+
{
|
|
7
|
+
label: 'props',
|
|
8
|
+
component: 'itemGroup',
|
|
9
|
+
name: 'props',
|
|
10
|
+
children: [
|
|
11
|
+
{
|
|
12
|
+
label: '显示模式',
|
|
13
|
+
component: 'radio',
|
|
14
|
+
name: 'mode',
|
|
15
|
+
props: {
|
|
16
|
+
mode: 'static',
|
|
17
|
+
options: [
|
|
18
|
+
{ label: '表格', value: 'table' },
|
|
19
|
+
{ label: '卡片', value: 'card' },
|
|
20
|
+
{ label: '行内', value: 'inline' }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
initialValue: 'table'
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { default as input } from './input'
|
|
2
|
+
export { default as select } from './select'
|
|
3
|
+
export { default as radio } from './radio'
|
|
4
|
+
export { default as card } from './card'
|
|
5
|
+
export { default as inputNumber } from './inputNumber'
|
|
6
|
+
export { default as switch } from './switch'
|
|
7
|
+
export { default as formList } from './formList'
|
|
8
|
+
export { default as itemGroup } from './itemGroup'
|
|
9
|
+
export { default as password } from './password'
|
|
10
|
+
export { default as textarea } from './textarea'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
items: [
|
|
3
|
+
{ label: '字段label', component: 'input', name: 'label' },
|
|
4
|
+
{ label: '字段标识', component: 'input', name: 'name' },
|
|
5
|
+
{ label: '字段说明', component: 'textarea', name: 'help' },
|
|
6
|
+
{ label: '初始值', component: 'input', name: 'initialValue' },
|
|
7
|
+
{ label: '是否必填', component: 'switch', name: 'required' },
|
|
8
|
+
{
|
|
9
|
+
label: 'props',
|
|
10
|
+
component: 'itemGroup',
|
|
11
|
+
name: 'props',
|
|
12
|
+
children: [
|
|
13
|
+
{ label: '是否禁用', component: 'switch', name: 'disabled' },
|
|
14
|
+
{
|
|
15
|
+
label: '占位提示',
|
|
16
|
+
component: 'input',
|
|
17
|
+
name: 'placeholder',
|
|
18
|
+
initialValue: '请输入...'
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
{ label: '隐藏条件', component: 'input', name: 'hidden' },
|
|
24
|
+
{
|
|
25
|
+
label: '联动值',
|
|
26
|
+
name: 'linkage',
|
|
27
|
+
component: 'formList',
|
|
28
|
+
children: [
|
|
29
|
+
{
|
|
30
|
+
label: '联动字段',
|
|
31
|
+
name: 'target',
|
|
32
|
+
component: 'input',
|
|
33
|
+
props: {}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: '值',
|
|
37
|
+
name: 'value',
|
|
38
|
+
component: 'input',
|
|
39
|
+
props: {}
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
props: {
|
|
43
|
+
mode: 'card'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|