1.增加栅格容器响应式布局设置;2.增加常见表单模板库。
parent
85aaca2dd0
commit
e33ce0c271
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "variant-form",
|
"name": "variant-form",
|
||||||
"version": "2.1.6",
|
"version": "2.1.7",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve --open src/main.js",
|
"serve": "vue-cli-service serve --open src/main.js",
|
||||||
|
@ -15,7 +15,6 @@
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"element-ui": "^2.15.1",
|
"element-ui": "^2.15.1",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"view-design": "^4.7.0-beta.10",
|
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-i18n": "^8.24.5",
|
"vue-i18n": "^8.24.5",
|
||||||
"vue2-editor": "^2.10.2",
|
"vue2-editor": "^2.10.2",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-col v-else-if="widget.type === 'grid-col'" class="grid-cell" :span="widget.options.span || 12"
|
<el-col v-else-if="widget.type === 'grid-col'" class="grid-cell" v-bind="layoutProps"
|
||||||
:offset="widget.options.offset || 0" :push="widget.options.push || 0" :pull="widget.options.pull || 0"
|
|
||||||
:class="[selected ? 'selected' : '', customClass]"
|
:class="[selected ? 'selected' : '', customClass]"
|
||||||
:key="widget.id" @click.native.stop="selectWidget(widget)">
|
:key="widget.id" @click.native.stop="selectWidget(widget)">
|
||||||
<draggable :list="widget.widgetList" v-bind="{group:'dragGroup', ghostClass: 'ghost',animation: 200}"
|
<draggable :list="widget.widgetList" v-bind="{group:'dragGroup', ghostClass: 'ghost',animation: 200}"
|
||||||
|
@ -58,6 +57,19 @@
|
||||||
indexOfParentList: Number,
|
indexOfParentList: Number,
|
||||||
designer: Object,
|
designer: Object,
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
layoutProps: {
|
||||||
|
span: this.widget.options.span || 12,
|
||||||
|
// md: this.widget.options.md || 12,
|
||||||
|
// sm: this.widget.options.sm || 12,
|
||||||
|
// xs: this.widget.options.xs || 12,
|
||||||
|
offset: this.widget.options.offset || 0,
|
||||||
|
push: this.widget.options.push || 0,
|
||||||
|
pull: this.widget.options.pull || 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
selected() {
|
selected() {
|
||||||
return this.widget.id === this.designer.selectedId
|
return this.widget.id === this.designer.selectedId
|
||||||
|
@ -69,9 +81,101 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
//
|
'designer.formConfig.layoutType': {
|
||||||
|
handler(val) {
|
||||||
|
if (!!this.widget.options.responsive) {
|
||||||
|
if (val === 'H5') {
|
||||||
|
this.layoutProps.span = this.widget.options.xs || 12
|
||||||
|
} else if (val === 'Pad') {
|
||||||
|
this.layoutProps.span = this.widget.options.sm || 12
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.md || 12
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.span || 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.responsive': {
|
||||||
|
handler(val) {
|
||||||
|
let lyType = this.designer.formConfig.layoutType
|
||||||
|
if (!!val) {
|
||||||
|
if (lyType === 'H5') {
|
||||||
|
this.layoutProps.span = this.widget.options.xs || 12
|
||||||
|
} else if (lyType === 'Pad') {
|
||||||
|
this.layoutProps.span = this.widget.options.sm || 12
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.md || 12
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.span || 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.span': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.span = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.md': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.span = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.sm': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.span = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.xs': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.span = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.offset': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.offset = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.push': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.push = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'widget.options.pull': {
|
||||||
|
handler(val) {
|
||||||
|
this.layoutProps.pull = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initLayoutProps()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initLayoutProps() {
|
||||||
|
if (!!this.widget.options.responsive) {
|
||||||
|
let lyType = this.designer.formConfig.layoutType
|
||||||
|
if (lyType === 'H5') {
|
||||||
|
this.layoutProps.span = this.widget.options.xs || 12
|
||||||
|
} else if (lyType === 'Pad') {
|
||||||
|
this.layoutProps.span = this.widget.options.sm || 12
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.md || 12
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.layoutProps.spn = this.widget.options.span
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
onGridDragEnd(evt, subList) {
|
onGridDragEnd(evt, subList) {
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
|
|
|
@ -98,6 +98,13 @@ export default {
|
||||||
this.handleOnChange(values[0], values[1])
|
this.handleOnChange(values[0], values[1])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* 监听重新加载选项事件 */
|
||||||
|
this.$on('reloadOptions', function (widgetNames) {
|
||||||
|
if ((widgetNames.length === 0) || (widgetNames.indexOf(this.field.options.name) > -1)) {
|
||||||
|
this.initOptionItems(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOnCreated() {
|
handleOnCreated() {
|
||||||
|
@ -141,7 +148,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initOptionItems() {
|
initOptionItems(keepSelected) {
|
||||||
if (this.designState) {
|
if (this.designState) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -149,7 +156,11 @@ export default {
|
||||||
if ((this.field.type === 'radio') || (this.field.type === 'checkbox')
|
if ((this.field.type === 'radio') || (this.field.type === 'checkbox')
|
||||||
|| (this.field.type === 'select') || (this.field.type === 'cascader')) {
|
|| (this.field.type === 'select') || (this.field.type === 'cascader')) {
|
||||||
if (!!this.globalOptionData && this.globalOptionData.hasOwnProperty(this.field.options.name)) {
|
if (!!this.globalOptionData && this.globalOptionData.hasOwnProperty(this.field.options.name)) {
|
||||||
this.loadOptions( this.globalOptionData[this.field.options.name] )
|
if (!!keepSelected) {
|
||||||
|
this.reloadOptions(this.globalOptionData[this.field.options.name])
|
||||||
|
} else {
|
||||||
|
this.loadOptions( this.globalOptionData[this.field.options.name] )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -165,6 +176,7 @@ export default {
|
||||||
if (!!this.field.options.required) {
|
if (!!this.field.options.required) {
|
||||||
this.rules.push({
|
this.rules.push({
|
||||||
required: true,
|
required: true,
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
message: this.i18nt('render.hint.fieldRequired'),
|
message: this.i18nt('render.hint.fieldRequired'),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -199,6 +211,37 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用字段值变动触发表单校验
|
||||||
|
*/
|
||||||
|
disableChangeValidate() {
|
||||||
|
if (!this.rules) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rules.forEach(rule => {
|
||||||
|
if (!!rule.trigger) {
|
||||||
|
rule.trigger.splice(0, rule.trigger.length)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用字段值变动触发表单校验
|
||||||
|
*/
|
||||||
|
enableChangeValidate() {
|
||||||
|
if (!this.rules) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rules.forEach(rule => {
|
||||||
|
if (!!rule.trigger) {
|
||||||
|
rule.trigger.push('blur')
|
||||||
|
rule.trigger.push('change')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
disableOptionOfList(optionList, optionValue) {
|
disableOptionOfList(optionList, optionValue) {
|
||||||
if (!!optionList && (optionList.length > 0)) {
|
if (!!optionList && (optionList.length > 0)) {
|
||||||
optionList.forEach(opt => {
|
optionList.forEach(opt => {
|
||||||
|
@ -365,7 +408,11 @@ export default {
|
||||||
|
|
||||||
resetField() {
|
resetField() {
|
||||||
let defaultValue = this.field.options.defaultValue
|
let defaultValue = this.field.options.defaultValue
|
||||||
|
//this.disableChangeValidate() /* 禁用字段校验 */
|
||||||
this.setValue(defaultValue)
|
this.setValue(defaultValue)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
//this.enableChangeValidate() /* 开启字段校验 */
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setWidgetOption(optionName, optionValue) { //通用组件选项修改API
|
setWidgetOption(optionName, optionValue) { //通用组件选项修改API
|
||||||
|
@ -423,11 +470,23 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载选项,并清空字段值
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
loadOptions(options) {
|
loadOptions(options) {
|
||||||
this.field.options.optionItems = deepClone(options)
|
this.field.options.optionItems = deepClone(options)
|
||||||
this.clearSelectedOptions() //清空已选选项
|
this.clearSelectedOptions() //清空已选选项
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新加载选项,不清空字段值
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
reloadOptions(options) {
|
||||||
|
this.field.options.optionItems = deepClone(options)
|
||||||
|
},
|
||||||
|
|
||||||
disableOption(optionValue) {
|
disableOption(optionValue) {
|
||||||
this.disableOptionOfList(this.field.options.optionItems, optionValue)
|
this.disableOptionOfList(this.field.options.optionItems, optionValue)
|
||||||
},
|
},
|
||||||
|
|
|
@ -160,6 +160,20 @@
|
||||||
return this.handleOnBeforeUpload(file)
|
return this.handleOnBeforeUpload(file)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleOnBeforeUpload(file) {
|
||||||
|
if (!!this.field.options.onBeforeUpload) {
|
||||||
|
let bfFunc = new Function('file', this.field.options.onBeforeUpload)
|
||||||
|
let result = bfFunc.call(this, file)
|
||||||
|
if (typeof result === 'boolean') {
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
handleFileUpload(res, file, fileList) {
|
handleFileUpload(res, file, fileList) {
|
||||||
if (!!this.field.options.onUploadSuccess) {
|
if (!!this.field.options.onUploadSuccess) {
|
||||||
let mountFunc = new Function('result', 'file', 'fileList', this.field.options.onUploadSuccess)
|
let mountFunc = new Function('result', 'file', 'fileList', this.field.options.onUploadSuccess)
|
||||||
|
|
|
@ -150,6 +150,20 @@
|
||||||
return this.handleOnBeforeUpload(file)
|
return this.handleOnBeforeUpload(file)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleOnBeforeUpload(file) {
|
||||||
|
if (!!this.field.options.onBeforeUpload) {
|
||||||
|
let bfFunc = new Function('file', this.field.options.onBeforeUpload)
|
||||||
|
let result = bfFunc.call(this, file)
|
||||||
|
if (typeof result === 'boolean') {
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
handlePictureUpload(res, file, fileList) {
|
handlePictureUpload(res, file, fileList) {
|
||||||
if (!!this.field.options.onUploadSuccess) {
|
if (!!this.field.options.onUploadSuccess) {
|
||||||
let customFn = new Function('result', 'file', 'fileList', this.field.options.onUploadSuccess)
|
let customFn = new Function('result', 'file', 'fileList', this.field.options.onUploadSuccess)
|
||||||
|
@ -160,6 +174,7 @@
|
||||||
this.updateUploadFieldModelAndEmitDataChange()
|
this.updateUploadFieldModelAndEmitDataChange()
|
||||||
|
|
||||||
this.uploadBtnHidden = this.fileList.length >= this.field.options.limit
|
this.uploadBtnHidden = this.fileList.length >= this.field.options.limit
|
||||||
|
//console.log('test========', this.uploadBtnHidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -211,7 +226,7 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep div.el-upload__tip { /* 隐藏最后的文件上传按钮 */
|
::v-deep div.el-upload__tip { /* 隐藏最后的文件上传按钮提示 */
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="form-widget-container">
|
<div class="form-widget-container">
|
||||||
|
|
||||||
<el-form class="full-height-width widget-form" :label-position="labelPosition"
|
<el-form class="full-height-width widget-form" :label-position="labelPosition"
|
||||||
:class="[customClass, layoutType === 'H5' ? 'h5-layout' : '']" :size="size" :validate-on-rule-change="false">
|
:class="[customClass, layoutType + '-layout']" :size="size" :validate-on-rule-change="false">
|
||||||
|
|
||||||
<div v-if="designer.widgetList.length === 0" class="no-widget-hint">{{i18nt('designer.noWidgetHint')}}</div>
|
<div v-if="designer.widgetList.length === 0" class="no-widget-hint">{{i18nt('designer.noWidgetHint')}}</div>
|
||||||
|
|
||||||
|
@ -216,7 +216,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form.h5-layout {
|
.el-form.PC-layout {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form.Pad-layout {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 960px;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 0 1px 10px #495060;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form.H5-layout {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 420px;
|
width: 420px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
|
|
|
@ -158,7 +158,7 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.get(MOCK_CASE_URL + this.caseName).then(res => {
|
axios.get(MOCK_CASE_URL + this.caseName + '.txt').then(res => {
|
||||||
if (!!res.data.code) {
|
if (!!res.data.code) {
|
||||||
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail'))
|
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail'))
|
||||||
return
|
return
|
||||||
|
@ -167,7 +167,7 @@
|
||||||
this.setFormJson(res.data)
|
this.setFormJson(res.data)
|
||||||
this.$message.success(this.i18nt('designer.hint.sampleLoadedSuccess'))
|
this.$message.success(this.i18nt('designer.hint.sampleLoadedSuccess'))
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail') + ':' +error)
|
this.$message.error(this.i18nt('designer.hint.sampleLoadedFail') + ':' + error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -200,11 +200,13 @@
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.designer.hasConfig(this.selectedWidget, propName)
|
let originalPropName = propName.replace(this.selectedWidget.type + '-', '') //去掉组件名称前缀-,如果有的话!!
|
||||||
|
return this.designer.hasConfig(this.selectedWidget, originalPropName)
|
||||||
},
|
},
|
||||||
|
|
||||||
getPropEditor(propName, editorName) {
|
getPropEditor(propName, editorName) {
|
||||||
let ownPropEditorName = `${this.selectedWidget.type}-${propName}-editor`
|
let originalPropName = propName.replace(this.selectedWidget.type + '-', '') //去掉组件名称前缀-,如果有的话!!
|
||||||
|
let ownPropEditorName = `${this.selectedWidget.type}-${originalPropName}-editor`
|
||||||
//console.log(ownPropEditorName, this.$options.components[ownPropEditorName])
|
//console.log(ownPropEditorName, this.$options.components[ownPropEditorName])
|
||||||
if (!!this.$options.components[ownPropEditorName]) { //局部注册的属性编辑器组件
|
if (!!this.$options.components[ownPropEditorName]) { //局部注册的属性编辑器组件
|
||||||
return ownPropEditorName
|
return ownPropEditorName
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<template>
|
||||||
|
<el-form-item :label="i18nt('designer.setting.responsive')">
|
||||||
|
<el-checkbox v-model="optionModel.responsive"></el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import i18n from "@/utils/i18n"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "grid-col-responsive-editor",
|
||||||
|
mixins: [i18n],
|
||||||
|
props: {
|
||||||
|
designer: Object,
|
||||||
|
selectedWidget: Object,
|
||||||
|
optionModel: Object,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,8 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form-item :label="i18nt('designer.setting.colSpanTitle')">
|
<div>
|
||||||
<el-input-number v-model.number="optionModel.span" :min="1" :max="24"
|
<el-form-item :label="i18nt('designer.setting.colSpanTitle')" v-if="!optionModel.responsive">
|
||||||
style="width: 100%"></el-input-number>
|
<el-input-number v-model.number="optionModel.span" :min="1" :max="24"
|
||||||
</el-form-item>
|
style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="i18nt('designer.setting.colSpanTitle') + '(PC)'"
|
||||||
|
v-if="!!optionModel.responsive && (formConfig.layoutType === 'PC')">
|
||||||
|
<el-input-number v-model.number="optionModel.md" :min="1" :max="24"
|
||||||
|
style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="i18nt('designer.setting.colSpanTitle') + '(Pad)'"
|
||||||
|
v-if="!!optionModel.responsive && (formConfig.layoutType === 'Pad')">
|
||||||
|
<el-input-number v-model.number="optionModel.sm" :min="1" :max="24"
|
||||||
|
style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="i18nt('designer.setting.colSpanTitle') + '(H5)'"
|
||||||
|
v-if="!!optionModel.responsive && (formConfig.layoutType === 'H5')">
|
||||||
|
<el-input-number v-model.number="optionModel.xs" :min="1" :max="24"
|
||||||
|
style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -16,6 +33,13 @@
|
||||||
selectedWidget: Object,
|
selectedWidget: Object,
|
||||||
optionModel: Object,
|
optionModel: Object,
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
formConfig() {
|
||||||
|
return this.designer.formConfig
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ const COMMON_PROPERTIES = {
|
||||||
'cellWidth' : 'cellWidth-editor',
|
'cellWidth' : 'cellWidth-editor',
|
||||||
'cellHeight' : 'cellHeight-editor',
|
'cellHeight' : 'cellHeight-editor',
|
||||||
'gutter' : 'gutter-editor',
|
'gutter' : 'gutter-editor',
|
||||||
|
'responsive' : 'responsive-editor',
|
||||||
'span' : 'span-editor',
|
'span' : 'span-editor',
|
||||||
'offset' : 'offset-editor',
|
'offset' : 'offset-editor',
|
||||||
'push' : 'push-editor',
|
'push' : 'push-editor',
|
||||||
|
@ -125,35 +126,66 @@ const EVENT_PROPERTIES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如属性编辑器的组件名称设置为null,则不显示该属性编辑器!!
|
* 注册组件常见属性
|
||||||
* @param propName 属性名称
|
* 如属性编辑器的组件名称propEditorName设置为null,则不显示该属性编辑器!!
|
||||||
|
* @param uniquePropName 属性名称(保证名称唯一,不跟其他组件属性冲突)
|
||||||
* @param propEditorName 对应属性编辑器的组件名称
|
* @param propEditorName 对应属性编辑器的组件名称
|
||||||
*/
|
*/
|
||||||
export function registerCommonProperty(propName, propEditorName) {
|
export function registerCommonProperty(uniquePropName, propEditorName) {
|
||||||
COMMON_PROPERTIES[propName] = propEditorName
|
COMMON_PROPERTIES[uniquePropName] = propEditorName
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerAdvancedProperty(propName, propEditorName) {
|
/**
|
||||||
ADVANCED_PROPERTIES[propName] = propEditorName
|
* 注册组件高级属性
|
||||||
|
* 如属性编辑器的组件名称propEditorName设置为null,则不显示该属性编辑器!!
|
||||||
|
* @param uniquePropName 属性名称(保证名称唯一,不跟其他组件属性冲突)
|
||||||
|
* @param propEditorName 对应属性编辑器的组件名称
|
||||||
|
*/
|
||||||
|
export function registerAdvancedProperty(uniquePropName, propEditorName) {
|
||||||
|
ADVANCED_PROPERTIES[uniquePropName] = propEditorName
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerEventProperty(propName, propEditorName) {
|
/**
|
||||||
EVENT_PROPERTIES[propName] = propEditorName
|
* 注册组件事件属性
|
||||||
|
* 如属性编辑器的组件名称propEditorName设置为null,则不显示该属性编辑器!!
|
||||||
|
* @param uniquePropName 属性名称(保证名称唯一,不跟其他组件属性冲突)
|
||||||
|
* @param propEditorName 对应属性编辑器的组件名称
|
||||||
|
*/
|
||||||
|
export function registerEventProperty(uniquePropName, propEditorName) {
|
||||||
|
EVENT_PROPERTIES[uniquePropName] = propEditorName
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerCPEditor(propName, propEditorName, editorComponent) {
|
/**
|
||||||
|
* 注册常见属性对应的属性编辑器
|
||||||
|
* @param uniquePropName
|
||||||
|
* @param propEditorName
|
||||||
|
* @param editorComponent
|
||||||
|
*/
|
||||||
|
export function registerCPEditor(uniquePropName, propEditorName, editorComponent) {
|
||||||
Vue.component(propEditorName, editorComponent)
|
Vue.component(propEditorName, editorComponent)
|
||||||
registerCommonProperty(propName, propEditorName)
|
registerCommonProperty(uniquePropName, propEditorName)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerAPEditor(propName, propEditorName, editorComponent) {
|
/**
|
||||||
|
* 注册高级属性对应的属性编辑器
|
||||||
|
* @param uniquePropName
|
||||||
|
* @param propEditorName
|
||||||
|
* @param editorComponent
|
||||||
|
*/
|
||||||
|
export function registerAPEditor(uniquePropName, propEditorName, editorComponent) {
|
||||||
Vue.component(propEditorName, editorComponent)
|
Vue.component(propEditorName, editorComponent)
|
||||||
registerAdvancedProperty(propName, propEditorName)
|
registerAdvancedProperty(uniquePropName, propEditorName)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerEPEditor(propName, propEditorName, editorComponent) {
|
/**
|
||||||
|
* 注册事件属性对应的属性编辑器
|
||||||
|
* @param uniquePropName
|
||||||
|
* @param propEditorName
|
||||||
|
* @param editorComponent
|
||||||
|
*/
|
||||||
|
export function registerEPEditor(uniquePropName, propEditorName, editorComponent) {
|
||||||
Vue.component(propEditorName, editorComponent)
|
Vue.component(propEditorName, editorComponent)
|
||||||
registerEventProperty(propName, propEditorName)
|
registerEventProperty(uniquePropName, propEditorName)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
<el-button-group style="margin-left: 20px">
|
<el-button-group style="margin-left: 20px">
|
||||||
<el-button :type="layoutType === 'PC' ? 'info': ''" @click="changeLayoutType('PC')">
|
<el-button :type="layoutType === 'PC' ? 'info': ''" @click="changeLayoutType('PC')">
|
||||||
{{i18nt('designer.toolbar.pcLayout')}}</el-button>
|
{{i18nt('designer.toolbar.pcLayout')}}</el-button>
|
||||||
|
<el-button :type="layoutType === 'Pad' ? 'info': ''" @click="changeLayoutType('Pad')">
|
||||||
|
{{i18nt('designer.toolbar.padLayout')}}</el-button>
|
||||||
<el-button :type="layoutType === 'H5' ? 'info': ''" @click="changeLayoutType('H5')">
|
<el-button :type="layoutType === 'H5' ? 'info': ''" @click="changeLayoutType('H5')">
|
||||||
{{i18nt('designer.toolbar.mobileLayout')}}</el-button>
|
{{i18nt('designer.toolbar.mobileLayout')}}</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
|
|
|
@ -55,9 +55,22 @@
|
||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane name="formLib" v-if="false">
|
<el-tab-pane name="formLib" style="padding: 8px">
|
||||||
<span slot="label"><i class="el-icon-c-scale-to-original"></i> {{i18nt('designer.formLib')}}</span>
|
<span slot="label"><i class="el-icon-c-scale-to-original"></i> {{i18nt('designer.formLib')}}</span>
|
||||||
|
|
||||||
|
<template v-for="(ft, idx) in formTemplates">
|
||||||
|
<el-card :bord-style="{ padding: '0' }" shadow="hover" class="ft-card">
|
||||||
|
<el-popover placement="right" trigger="hover">
|
||||||
|
<img slot="reference" :src="ft.imgUrl" style="width: 200px">
|
||||||
|
<img :src="ft.imgUrl" style="height: 600px;width: 720px">
|
||||||
|
</el-popover>
|
||||||
|
<div class="bottom clear-fix">
|
||||||
|
<span class="ft-title">#{{idx+1}} {{ft.title}}</span>
|
||||||
|
<el-button type="text" class="right-button" @click="loadFormTemplate(ft.jsonUrl)">
|
||||||
|
{{i18nt('designer.hint.loadFormTemplate')}}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
@ -68,9 +81,11 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Draggable from 'vuedraggable'
|
import Draggable from 'vuedraggable'
|
||||||
import {containers, basicFields, advancedFields, customFields} from "./widgetsConfig";
|
import {containers, basicFields, advancedFields, customFields} from "./widgetsConfig"
|
||||||
import {addWindowResizeHandler} from "@/utils/util";
|
import {formTemplates} from './templatesConfig'
|
||||||
import i18n from "@/utils/i18n";
|
import {addWindowResizeHandler} from "@/utils/util"
|
||||||
|
import i18n from "@/utils/i18n"
|
||||||
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FieldPanel",
|
name: "FieldPanel",
|
||||||
|
@ -94,7 +109,7 @@
|
||||||
advancedFields,
|
advancedFields,
|
||||||
customFields,
|
customFields,
|
||||||
|
|
||||||
allContainers: [],
|
formTemplates: formTemplates,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -113,8 +128,6 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadWidgets() {
|
loadWidgets() {
|
||||||
//this.allContainers = deepClone(this.containers)
|
|
||||||
|
|
||||||
this.containers = this.containers.map(con => {
|
this.containers = this.containers.map(con => {
|
||||||
return {
|
return {
|
||||||
...con,
|
...con,
|
||||||
|
@ -168,10 +181,34 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
addFieldByDbClick(widget) {
|
addFieldByDbClick(widget) {
|
||||||
//console.log('addWidgetByDbClick')
|
|
||||||
this.designer.addFieldByDbClick(widget)
|
this.designer.addFieldByDbClick(widget)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadFormTemplate(jsonUrl) {
|
||||||
|
this.$confirm(this.i18nt('designer.hint.loadFormTemplateHint'), this.i18nt('render.hint.prompt'), {
|
||||||
|
confirmButtonText: this.i18nt('render.hint.confirm'),
|
||||||
|
cancelButtonText: this.i18nt('render.hint.cancel')
|
||||||
|
}).then(() => {
|
||||||
|
axios.get(jsonUrl).then(res => {
|
||||||
|
let modifiedFlag = false
|
||||||
|
if (typeof res.data === 'string') {
|
||||||
|
modifiedFlag = this.designer.loadFormJson( JSON.parse(res.data) )
|
||||||
|
} else if (res.data.constructor === Object) {
|
||||||
|
modifiedFlag = this.designer.loadFormJson(res.data)
|
||||||
|
}
|
||||||
|
if (modifiedFlag) {
|
||||||
|
this.designer.emitHistoryChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$message.success(this.i18nt('designer.hint.loadFormTemplateSuccess'))
|
||||||
|
}).catch(error => {
|
||||||
|
this.$message.error(this.i18nt('designer.hint.loadFormTemplateFailed') + ':' + error)
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
console.error(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -179,18 +216,12 @@
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.side-scroll-bar {
|
.side-scroll-bar {
|
||||||
//height: calc(100% - 56px);
|
|
||||||
//height: 100%;
|
|
||||||
|
|
||||||
::v-deep .el-scrollbar__wrap {
|
::v-deep .el-scrollbar__wrap {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.panel-container {
|
div.panel-container {
|
||||||
//height: calc(100% - 48px);
|
|
||||||
//height: 100%;
|
|
||||||
//overflow-y: hidden;
|
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,4 +297,44 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-card.ft-card {
|
||||||
|
border: 1px solid #8896B3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ft-card {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
margin-top: 10px;
|
||||||
|
line-height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.image-zoom {
|
||||||
|
height: 500px;
|
||||||
|
width: 620px
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ft-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-button {
|
||||||
|
padding: 0;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-fix:before, .clear-fix:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-fix:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
export const formTemplates = [
|
||||||
|
{
|
||||||
|
title: '单列表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t1.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json1.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '多列表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t2.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json2.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '分组表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t3.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json3.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '标签页表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t4.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json4.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '主从表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t5.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json5.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '响应式表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t6.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json6.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '问卷调查表',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t7.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json7.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '固定表格表单',
|
||||||
|
imgUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/t8.png',
|
||||||
|
jsonUrl: 'https://ks3-cn-beijing.ksyuncs.com/vform-static/form-samples/json8.txt',
|
||||||
|
description: '表单模板详细说明...'
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
|
@ -65,6 +65,10 @@ export const containers = [
|
||||||
offset: 0,
|
offset: 0,
|
||||||
push: 0,
|
push: 0,
|
||||||
pull: 0,
|
pull: 0,
|
||||||
|
responsive: false, //是否开启响应式布局
|
||||||
|
md: 12,
|
||||||
|
sm: 12,
|
||||||
|
xs: 12,
|
||||||
customClass: '', //自定义css类名
|
customClass: '', //自定义css类名
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-col class="grid-cell" :span="widget.options.span" :class="[customClass]"
|
<el-col class="grid-cell" :class="[customClass]" v-bind="layoutProps"
|
||||||
:offset="widget.options.offset || 0" :push="widget.options.push || 0" :pull="widget.options.pull || 0"
|
|
||||||
:key="widget.id" v-show="!widget.options.hidden">
|
:key="widget.id" v-show="!widget.options.hidden">
|
||||||
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
|
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
|
||||||
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
||||||
|
@ -40,7 +39,20 @@
|
||||||
parentList: Array,
|
parentList: Array,
|
||||||
indexOfParentList: Number,
|
indexOfParentList: Number,
|
||||||
},
|
},
|
||||||
inject: ['refList', 'globalModel'],
|
inject: ['refList', 'globalModel', 'formConfig', 'previewState'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
layoutProps: {
|
||||||
|
span: this.widget.options.span,
|
||||||
|
md: this.widget.options.md || 12,
|
||||||
|
sm: this.widget.options.sm || 12,
|
||||||
|
xs: this.widget.options.xs || 12,
|
||||||
|
offset: this.widget.options.offset || 0,
|
||||||
|
push: this.widget.options.push || 0,
|
||||||
|
pull: this.widget.options.pull || 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
customClass() {
|
customClass() {
|
||||||
return this.widget.options.customClass || ''
|
return this.widget.options.customClass || ''
|
||||||
|
@ -48,8 +60,36 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.initLayoutProps()
|
||||||
this.initRefList()
|
this.initRefList()
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
initLayoutProps() {
|
||||||
|
if (!!this.widget.options.responsive) {
|
||||||
|
if (!!this.previewState) {
|
||||||
|
this.layoutProps.md = undefined
|
||||||
|
this.layoutProps.sm = undefined
|
||||||
|
this.layoutProps.xs = undefined
|
||||||
|
|
||||||
|
let lyType = this.formConfig.layoutType
|
||||||
|
if (lyType === 'H5') {
|
||||||
|
this.layoutProps.span = this.widget.options.xs || 12
|
||||||
|
} else if (lyType === 'Pad') {
|
||||||
|
this.layoutProps.span = this.widget.options.sm || 12
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = this.widget.options.md || 12
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.layoutProps.span = undefined
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.layoutProps.md = undefined
|
||||||
|
this.layoutProps.sm = undefined
|
||||||
|
this.layoutProps.xs = undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@
|
||||||
td.table-cell {
|
td.table-cell {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border: 1px dashed #336699;
|
//border: 1px dashed #336699;
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -53,6 +53,10 @@
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {}
|
||||||
},
|
},
|
||||||
|
previewState: { //是否表单预览状态
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
|
@ -62,7 +66,8 @@
|
||||||
globalOptionData: this.optionData,
|
globalOptionData: this.optionData,
|
||||||
globalModel: {
|
globalModel: {
|
||||||
formModel: this.formDataModel,
|
formModel: this.formDataModel,
|
||||||
}
|
},
|
||||||
|
previewState: this.previewState,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -163,14 +168,6 @@
|
||||||
this.buildDataFromWidget(wItem)
|
this.buildDataFromWidget(wItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!this.formJsonObj || !this.widgetList) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// this.widgetList.forEach((wItem) => {
|
|
||||||
// this.buildDataFromWidget(wItem)
|
|
||||||
// })
|
|
||||||
},
|
},
|
||||||
|
|
||||||
buildDataFromWidget(wItem) {
|
buildDataFromWidget(wItem) {
|
||||||
|
@ -354,6 +351,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新加载选项数据
|
||||||
|
* @param widgetNames 指定重新加载的组件名称或组件名数组,不传则重新加载所有选项字段
|
||||||
|
*/
|
||||||
|
reloadOptionData(widgetNames) {
|
||||||
|
let eventParams = []
|
||||||
|
if (!!widgetNames && (typeof widgetNames === 'string')) {
|
||||||
|
eventParams = [widgetNames]
|
||||||
|
} else if (!!widgetNames && Array.isArray(widgetNames)) {
|
||||||
|
eventParams = [...widgetNames]
|
||||||
|
}
|
||||||
|
this.broadcast('FieldWidget', 'reloadOptions', [eventParams])
|
||||||
|
},
|
||||||
|
|
||||||
getFormData(needValidation = true) {
|
getFormData(needValidation = true) {
|
||||||
if (!needValidation) {
|
if (!needValidation) {
|
||||||
return this.formDataModel
|
return this.formDataModel
|
||||||
|
@ -361,7 +372,7 @@
|
||||||
|
|
||||||
let callback = function nullFunc() {}
|
let callback = function nullFunc() {}
|
||||||
let promise = new window.Promise(function (resolve, reject) {
|
let promise = new window.Promise(function (resolve, reject) {
|
||||||
callback = function callback(formData, error) {
|
callback = function(formData, error) {
|
||||||
!error ? resolve(formData) : reject(error);
|
!error ? resolve(formData) : reject(error);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -465,7 +476,13 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.$refs.renderForm.clearValidate()
|
this.$nextTick(() => {
|
||||||
|
this.clearValidate() /* 清除resetField方法触发的校验错误提示 */
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
clearValidate(props) {
|
||||||
|
this.$refs.renderForm.clearValidate(props)
|
||||||
},
|
},
|
||||||
|
|
||||||
validateForm() {
|
validateForm() {
|
||||||
|
|
|
@ -33,13 +33,13 @@ export const loadExtension = function () {
|
||||||
Vue.component(CardWidget.name, CardWidget) //注册设计期的容器组件
|
Vue.component(CardWidget.name, CardWidget) //注册设计期的容器组件
|
||||||
Vue.component(CardItem.name, CardItem) //注册运行期的容器组件
|
Vue.component(CardItem.name, CardItem) //注册运行期的容器组件
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
PERegister.registerCPEditor('folded', 'card-folded-editor',
|
PERegister.registerCPEditor('card-folded', 'card-folded-editor',
|
||||||
PEFactory.createBooleanEditor('folded', 'extension.setting.cardFolded'))
|
PEFactory.createBooleanEditor('folded', 'extension.setting.cardFolded'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('showFold', 'card-showFold-editor',
|
PERegister.registerCPEditor('card-showFold', 'card-showFold-editor',
|
||||||
PEFactory.createBooleanEditor('showFold', 'extension.setting.cardShowFold'))
|
PEFactory.createBooleanEditor('showFold', 'extension.setting.cardShowFold'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('cardWidth', 'card-cardWidth-editor',
|
PERegister.registerCPEditor('card-cardWidth', 'card-cardWidth-editor',
|
||||||
PEFactory.createInputTextEditor('cardWidth', 'extension.setting.cardWidth'))
|
PEFactory.createInputTextEditor('cardWidth', 'extension.setting.cardWidth'))
|
||||||
|
|
||||||
let shadowOptions = [
|
let shadowOptions = [
|
||||||
|
@ -47,7 +47,7 @@ export const loadExtension = function () {
|
||||||
{label: 'hover', value: 'hover'},
|
{label: 'hover', value: 'hover'},
|
||||||
{label: 'always', value: 'always'},
|
{label: 'always', value: 'always'},
|
||||||
]
|
]
|
||||||
PERegister.registerCPEditor('shadow', 'card-shadow-editor',
|
PERegister.registerCPEditor('card-shadow', 'card-shadow-editor',
|
||||||
PEFactory.createSelectEditor('shadow', 'extension.setting.cardShadow',
|
PEFactory.createSelectEditor('shadow', 'extension.setting.cardShadow',
|
||||||
{optionItems: shadowOptions}))
|
{optionItems: shadowOptions}))
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
@ -67,7 +67,7 @@ export const loadExtension = function () {
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
Vue.component(AlertWidget.name, AlertWidget) //注册组件
|
Vue.component(AlertWidget.name, AlertWidget) //注册组件
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
PERegister.registerCPEditor('title', 'alert-title-editor',
|
PERegister.registerCPEditor('alert-title', 'alert-title-editor',
|
||||||
PEFactory.createInputTextEditor('title', 'extension.setting.alertTitle'))
|
PEFactory.createInputTextEditor('title', 'extension.setting.alertTitle'))
|
||||||
|
|
||||||
let typeOptions = [
|
let typeOptions = [
|
||||||
|
@ -76,34 +76,34 @@ export const loadExtension = function () {
|
||||||
{label: 'info', value: 'info'},
|
{label: 'info', value: 'info'},
|
||||||
{label: 'error', value: 'error'},
|
{label: 'error', value: 'error'},
|
||||||
]
|
]
|
||||||
PERegister.registerCPEditor('type', 'alert-type-editor',
|
PERegister.registerCPEditor('alert-type', 'alert-type-editor',
|
||||||
PEFactory.createSelectEditor('type', 'extension.setting.alertType',
|
PEFactory.createSelectEditor('type', 'extension.setting.alertType',
|
||||||
{optionItems: typeOptions}))
|
{optionItems: typeOptions}))
|
||||||
|
|
||||||
PERegister.registerCPEditor('description', 'alert-description-editor',
|
PERegister.registerCPEditor('alert-description', 'alert-description-editor',
|
||||||
PEFactory.createInputTextEditor('description', 'extension.setting.description'))
|
PEFactory.createInputTextEditor('description', 'extension.setting.description'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('closable', 'alert-closable-editor',
|
PERegister.registerCPEditor('alert-closable', 'alert-closable-editor',
|
||||||
PEFactory.createBooleanEditor('closable', 'extension.setting.closable'))
|
PEFactory.createBooleanEditor('closable', 'extension.setting.closable'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('closeText', 'alert-closeText-editor',
|
PERegister.registerCPEditor('alert-closeText', 'alert-closeText-editor',
|
||||||
PEFactory.createInputTextEditor('closeText', 'extension.setting.closeText'))
|
PEFactory.createInputTextEditor('closeText', 'extension.setting.closeText'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('center', 'alert-center-editor',
|
PERegister.registerCPEditor('alert-center', 'alert-center-editor',
|
||||||
PEFactory.createBooleanEditor('center', 'extension.setting.center'))
|
PEFactory.createBooleanEditor('center', 'extension.setting.center'))
|
||||||
|
|
||||||
PERegister.registerCPEditor('showIcon', 'alert-showIcon-editor',
|
PERegister.registerCPEditor('alert-showIcon', 'alert-showIcon-editor',
|
||||||
PEFactory.createBooleanEditor('showIcon', 'extension.setting.showIcon'))
|
PEFactory.createBooleanEditor('showIcon', 'extension.setting.showIcon'))
|
||||||
|
|
||||||
let effectOptions = [
|
let effectOptions = [
|
||||||
{label: 'light', value: 'light'},
|
{label: 'light', value: 'light'},
|
||||||
{label: 'dark', value: 'dark'},
|
{label: 'dark', value: 'dark'},
|
||||||
]
|
]
|
||||||
PERegister.registerCPEditor('effect', 'alert-effect-editor',
|
PERegister.registerCPEditor('alert-effect', 'alert-effect-editor',
|
||||||
PEFactory.createRadioButtonGroupEditor('effect', 'extension.setting.effect',
|
PEFactory.createRadioButtonGroupEditor('effect', 'extension.setting.effect',
|
||||||
{optionItems: effectOptions}))
|
{optionItems: effectOptions}))
|
||||||
|
|
||||||
PERegister.registerEPEditor('onClose', 'alert-onClose-editor',
|
PERegister.registerEPEditor('alert-onClose', 'alert-onClose-editor',
|
||||||
PEFactory.createEventHandlerEditor('onClose', []))
|
PEFactory.createEventHandlerEditor('onClose', []))
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
registerFWGenerator('alert', alertTemplateGenerator) //注册字段组件的代码生成器
|
registerFWGenerator('alert', alertTemplateGenerator) //注册字段组件的代码生成器
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
:ref="widget.id" v-show="!widget.options.hidden">
|
:ref="widget.id" v-show="!widget.options.hidden">
|
||||||
<div slot="header" class="clear-fix">
|
<div slot="header" class="clear-fix">
|
||||||
<span>{{widget.options.label}}</span>
|
<span>{{widget.options.label}}</span>
|
||||||
<i class="float-right" :class="[!widget.options.folded ? 'el-icon-arrow-down' : 'el-icon-arrow-up']" @click="toggleCard"></i>
|
<i v-if="widget.options.showFold" class="float-right"
|
||||||
|
:class="[!widget.options.folded ? 'el-icon-arrow-down' : 'el-icon-arrow-up']" @click="toggleCard"></i>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
|
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
|
||||||
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {buildClassAttr, buildContainerWidget, buildFieldWidget} from '@/utils/sf
|
||||||
|
|
||||||
export const cardTemplateGenerator = function (cw, formConfig) {
|
export const cardTemplateGenerator = function (cw, formConfig) {
|
||||||
const wop = cw.options
|
const wop = cw.options
|
||||||
const headerAttr = `header="${wop.label}"`
|
//const headerAttr = `header="${wop.label}"`
|
||||||
const classAttr = buildClassAttr(cw)
|
const classAttr = buildClassAttr(cw)
|
||||||
const styleAttr = !!wop.cardWidth ? `style="{width: ${wop.cardWidth} !important}"` : ''
|
const styleAttr = !!wop.cardWidth ? `style="{width: ${wop.cardWidth} !important}"` : ''
|
||||||
const shadowAttr = `shadow="${wop.shadow}"`
|
const shadowAttr = `shadow="${wop.shadow}"`
|
||||||
|
@ -10,7 +10,11 @@ export const cardTemplateGenerator = function (cw, formConfig) {
|
||||||
|
|
||||||
const cardTemplate =
|
const cardTemplate =
|
||||||
`<div class="card-container">
|
`<div class="card-container">
|
||||||
<el-card ${headerAttr} ${classAttr} ${styleAttr} ${shadowAttr} ${vShowAttr}>
|
<el-card ${classAttr} ${styleAttr} ${shadowAttr} ${vShowAttr}>
|
||||||
|
<div slot="header" class="clear-fix">
|
||||||
|
<span>${wop.label}</span>
|
||||||
|
${!!wop.showFold ? `<i class="float-right el-icon-arrow-down"></i>` : ''}
|
||||||
|
</div>
|
||||||
${
|
${
|
||||||
cw.widgetList.map(wItem => {
|
cw.widgetList.map(wItem => {
|
||||||
if (wItem.category === 'container') {
|
if (wItem.category === 'container') {
|
||||||
|
|
|
@ -108,6 +108,10 @@ export default {
|
||||||
fileNameInputPlaceholder: 'Enter the file name',
|
fileNameInputPlaceholder: 'Enter the file name',
|
||||||
sampleLoadedSuccess: 'Example loaded successfully',
|
sampleLoadedSuccess: 'Example loaded successfully',
|
||||||
sampleLoadedFail: 'Sample load failed',
|
sampleLoadedFail: 'Sample load failed',
|
||||||
|
loadFormTemplate: 'Load This',
|
||||||
|
loadFormTemplateHint: 'Are you sure to load this template?',
|
||||||
|
loadFormTemplateSuccess: 'Load form template success!',
|
||||||
|
loadFormTemplateFailed: 'Load form template failed.',
|
||||||
|
|
||||||
widgetSetting: 'Widget Config',
|
widgetSetting: 'Widget Config',
|
||||||
formSetting: 'Form Config',
|
formSetting: 'Form Config',
|
||||||
|
@ -141,6 +145,7 @@ export default {
|
||||||
undoHint: 'Undo',
|
undoHint: 'Undo',
|
||||||
redoHint: 'Redo',
|
redoHint: 'Redo',
|
||||||
pcLayout: 'PC',
|
pcLayout: 'PC',
|
||||||
|
padLayout: 'Pad',
|
||||||
mobileLayout: 'H5',
|
mobileLayout: 'H5',
|
||||||
clear: 'Clear',
|
clear: 'Clear',
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
|
@ -226,6 +231,7 @@ export default {
|
||||||
colPushTitle: 'Push Of Col',
|
colPushTitle: 'Push Of Col',
|
||||||
colPullTitle: 'Pull Of Col',
|
colPullTitle: 'Pull Of Col',
|
||||||
addColumn: 'Add Column',
|
addColumn: 'Add Column',
|
||||||
|
responsive: 'Responsive',
|
||||||
|
|
||||||
tabPaneSetting: 'Tab Panes',
|
tabPaneSetting: 'Tab Panes',
|
||||||
addTabPane: 'Add Tab Pane',
|
addTabPane: 'Add Tab Pane',
|
||||||
|
|
|
@ -108,6 +108,10 @@ export default {
|
||||||
fileNameInputPlaceholder: '请输入文件名',
|
fileNameInputPlaceholder: '请输入文件名',
|
||||||
sampleLoadedSuccess: '表单示例加载成功',
|
sampleLoadedSuccess: '表单示例加载成功',
|
||||||
sampleLoadedFail: '表单示例加载失败',
|
sampleLoadedFail: '表单示例加载失败',
|
||||||
|
loadFormTemplate: '加载此模板',
|
||||||
|
loadFormTemplateHint: '是否加载这个模板?加载后会覆盖设计器当前表单,你可以使用“撤销”功能恢复。',
|
||||||
|
loadFormTemplateSuccess: '表单模板加载成功',
|
||||||
|
loadFormTemplateFailed: '表单模板加载失败',
|
||||||
|
|
||||||
widgetSetting: '组件设置',
|
widgetSetting: '组件设置',
|
||||||
formSetting: '表单设置',
|
formSetting: '表单设置',
|
||||||
|
@ -141,6 +145,7 @@ export default {
|
||||||
undoHint: '撤销',
|
undoHint: '撤销',
|
||||||
redoHint: '重做',
|
redoHint: '重做',
|
||||||
pcLayout: 'PC',
|
pcLayout: 'PC',
|
||||||
|
padLayout: 'Pad',
|
||||||
mobileLayout: 'H5',
|
mobileLayout: 'H5',
|
||||||
clear: '清空',
|
clear: '清空',
|
||||||
preview: '预览',
|
preview: '预览',
|
||||||
|
@ -226,6 +231,7 @@ export default {
|
||||||
colPushTitle: '右移栅格数',
|
colPushTitle: '右移栅格数',
|
||||||
colPullTitle: '左移栅格数',
|
colPullTitle: '左移栅格数',
|
||||||
addColumn: '增加栅格',
|
addColumn: '增加栅格',
|
||||||
|
responsive: '响应式布局',
|
||||||
|
|
||||||
tabPaneSetting: '选项卡设置',
|
tabPaneSetting: '选项卡设置',
|
||||||
addTabPane: '增加选项卡页',
|
addTabPane: '增加选项卡页',
|
||||||
|
|
|
@ -8,9 +8,10 @@ export const DESIGNER_OPTIONS = {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VARIANT_FORM_VERSION = '2.1.6'
|
export const VARIANT_FORM_VERSION = '2.1.7'
|
||||||
|
|
||||||
export const MOCK_CASE_URL = 'https://www.fastmock.site/mock/2de212e0dc4b8e0885fea44ab9f2e1d0/vform/'
|
//export const MOCK_CASE_URL = 'https://www.fastmock.site/mock/2de212e0dc4b8e0885fea44ab9f2e1d0/vform/'
|
||||||
|
export const MOCK_CASE_URL = 'https://ks3-cn-beijing.ksyuncs.com/vform-static/vcase/'
|
||||||
|
|
||||||
//export const ACE_BASE_PATH = 'public/lib/ace/src-min-noconflict'
|
//export const ACE_BASE_PATH = 'public/lib/ace/src-min-noconflict'
|
||||||
export const ACE_BASE_PATH = 'https://ks3-cn-beijing.ksyun.com/vform2021/ace-mini'
|
export const ACE_BASE_PATH = 'https://ks3-cn-beijing.ksyun.com/vform2021/ace-mini'
|
||||||
|
|
|
@ -18,8 +18,15 @@ const containerTemplates = { //容器组件属性
|
||||||
`<el-row ${gridClassAttr}>
|
`<el-row ${gridClassAttr}>
|
||||||
${ctn.cols.map(col => {
|
${ctn.cols.map(col => {
|
||||||
const colOpt = col.options
|
const colOpt = col.options
|
||||||
|
const spanAttr = !!colOpt.responsive ? '' : `:span="${colOpt.span}"`
|
||||||
|
const mdAttr = !colOpt.responsive ? '' : `:md="${colOpt.md}"`
|
||||||
|
const smAttr = !colOpt.responsive ? '' : `:sm="${colOpt.sm}"`
|
||||||
|
const xsAttr = !colOpt.responsive ? '' : `:xs="${colOpt.xs}"`
|
||||||
|
const offsetAttr = !!colOpt.offset ? `:offset="${colOpt.offset}"` : ''
|
||||||
|
const pushAttr = !!colOpt.push ? `:push="${colOpt.push}"` : ''
|
||||||
|
const pullAttr = !!colOpt.pull ? `:pull="${colOpt.pull}"` : ''
|
||||||
const colClassAttr = buildClassAttr(col, 'grid-cell')
|
const colClassAttr = buildClassAttr(col, 'grid-cell')
|
||||||
return `<el-col :span="${colOpt.span}" ${colClassAttr}>
|
return `<el-col ${spanAttr} ${mdAttr} ${smAttr} ${xsAttr} ${offsetAttr} ${pushAttr} ${pullAttr} ${colClassAttr}>
|
||||||
${col.widgetList.map(cw => {
|
${col.widgetList.map(cw => {
|
||||||
if (cw.category === 'container') {
|
if (cw.category === 'container') {
|
||||||
return buildContainerWidget(cw, formConfig)
|
return buildContainerWidget(cw, formConfig)
|
||||||
|
@ -430,8 +437,9 @@ function genTemplate(formConfig, widgetList, vue3Flag = false) {
|
||||||
const genGlobalCSS = function (formConfig) {
|
const genGlobalCSS = function (formConfig) {
|
||||||
const globalCssTemplate =
|
const globalCssTemplate =
|
||||||
` .el-input-number.full-width-input, .el-cascader.full-width-input {
|
` .el-input-number.full-width-input, .el-cascader.full-width-input {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item--medium {
|
.el-form-item--medium {
|
||||||
.el-radio {
|
.el-radio {
|
||||||
line-height: 36px !important;
|
line-height: 36px !important;
|
||||||
|
@ -461,6 +469,19 @@ const genGlobalCSS = function (formConfig) {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clear-fix:before, .clear-fix:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-fix:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
${formConfig.cssCode}`
|
${formConfig.cssCode}`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue