1.表单设计器增加初始化属性;2.增加组件层次结构树视图;3.修复少量bug。
|
@ -9,7 +9,7 @@
|
||||||
[在线Demo](http://demo.vform666.com)
|
[在线Demo](http://demo.vform666.com)
|
||||||
|
|
||||||
### 友情链接
|
### 友情链接
|
||||||
[fantastic-admin](https://hooray.gitee.io/fantastic-admin/) —— 一款开箱即用的 Vue 中后台管理系统框架(支持Vue2/Vue3)
|
[Fantastic-admin](https://hooray.gitee.io/fantastic-admin/) —— 一款开箱即用的 Vue 中后台管理系统框架(支持Vue2/Vue3)
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "variant-form",
|
"name": "variant-form",
|
||||||
"version": "2.1.7",
|
"version": "2.1.8",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve --open src/main.js",
|
"serve": "vue-cli-service serve --open src/main.js",
|
||||||
|
|
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 50 KiB |
|
@ -62,7 +62,7 @@ export function createDesigner(vueInstance) {
|
||||||
this.initHistoryData()
|
this.initHistoryData()
|
||||||
},
|
},
|
||||||
|
|
||||||
clearDesigner() {
|
clearDesigner(skipHistoryChange) {
|
||||||
let emptyWidgetListFlag = (this.widgetList.length === 0)
|
let emptyWidgetListFlag = (this.widgetList.length === 0)
|
||||||
this.widgetList = []
|
this.widgetList = []
|
||||||
this.selectedId = null
|
this.selectedId = null
|
||||||
|
@ -70,7 +70,9 @@ export function createDesigner(vueInstance) {
|
||||||
this.selectedWidget = {} //this.selectedWidget = null
|
this.selectedWidget = {} //this.selectedWidget = null
|
||||||
overwriteObj(this.formConfig, defaultFormConfig) //
|
overwriteObj(this.formConfig, defaultFormConfig) //
|
||||||
|
|
||||||
if (!emptyWidgetListFlag) {
|
if (!!skipHistoryChange) {
|
||||||
|
//什么也不做!!
|
||||||
|
} else if (!emptyWidgetListFlag) {
|
||||||
this.emitHistoryChange()
|
this.emitHistoryChange()
|
||||||
} else {
|
} else {
|
||||||
this.saveCurrentHistoryStep()
|
this.saveCurrentHistoryStep()
|
||||||
|
@ -618,7 +620,14 @@ export function createDesigner(vueInstance) {
|
||||||
let newWidget = this.copyNewFieldWidget(widget)
|
let newWidget = this.copyNewFieldWidget(widget)
|
||||||
if (!!this.selectedWidget && this.selectedWidget.type === 'tab') {
|
if (!!this.selectedWidget && this.selectedWidget.type === 'tab') {
|
||||||
//获取当前激活的tabPane
|
//获取当前激活的tabPane
|
||||||
//TODO:
|
let activeTab = this.selectedWidget.tabs[0]
|
||||||
|
this.selectedWidget.tabs.forEach(tabPane => {
|
||||||
|
if (!!tabPane.options.active) {
|
||||||
|
activeTab = tabPane
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
!!activeTab && activeTab.widgetList.push(newWidget)
|
||||||
} else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
|
} else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
|
||||||
this.selectedWidget.widgetList.push(newWidget)
|
this.selectedWidget.widgetList.push(newWidget)
|
||||||
} else {
|
} else {
|
||||||
|
@ -626,6 +635,7 @@ export function createDesigner(vueInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setSelected(newWidget)
|
this.setSelected(newWidget)
|
||||||
|
this.designer.emitHistoryChange()
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteColOfGrid(gridWidget, colIdx) {
|
deleteColOfGrid(gridWidget, colIdx) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-col v-else-if="widget.type === 'grid-col'" class="grid-cell" v-bind="layoutProps"
|
<el-col v-else-if="widget.type === 'grid-col'" class="grid-cell" v-bind="layoutProps"
|
||||||
:class="[selected ? 'selected' : '', customClass]"
|
:class="[selected ? 'selected' : '', customClass]" :style="colHeightStyle"
|
||||||
: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}"
|
||||||
handle=".drag-handler" @end="(evt) => onGridDragEnd(evt, widget.widgetList)"
|
handle=".drag-handler" @end="(evt) => onGridDragEnd(evt, widget.widgetList)"
|
||||||
|
@ -56,6 +56,12 @@
|
||||||
parentList: Array,
|
parentList: Array,
|
||||||
indexOfParentList: Number,
|
indexOfParentList: Number,
|
||||||
designer: Object,
|
designer: Object,
|
||||||
|
|
||||||
|
colHeight: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -79,6 +85,10 @@
|
||||||
return this.widget.options.customClass || ''
|
return this.widget.options.customClass || ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
colHeightStyle() {
|
||||||
|
return !!this.colHeight ? {height: this.colHeight + 'px'} : {}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'designer.formConfig.layoutType': {
|
'designer.formConfig.layoutType': {
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
@click.native.stop="selectWidget(widget)">
|
@click.native.stop="selectWidget(widget)">
|
||||||
<template v-for="(colWidget, colIdx) in widget.cols">
|
<template v-for="(colWidget, colIdx) in widget.cols">
|
||||||
<grid-col-widget :widget="colWidget" :designer="designer" :key="colWidget.id" :parent-list="widget.cols"
|
<grid-col-widget :widget="colWidget" :designer="designer" :key="colWidget.id" :parent-list="widget.cols"
|
||||||
:index-of-parent-list="colIdx" :parent-widget="widget"></grid-col-widget>
|
:index-of-parent-list="colIdx" :parent-widget="widget"
|
||||||
|
:col-height="widget.options.colHeight"></grid-col-widget>
|
||||||
</template>
|
</template>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {deepClone} from "@/utils/util"
|
||||||
import FormValidators from '@/utils/validators'
|
import FormValidators from '@/utils/validators'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['refList', 'formConfig', 'globalOptionData', 'globalModel'],
|
inject: ['refList', 'formConfig', 'globalOptionData', 'globalModel', 'getOptionData'],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
subFormName() {
|
subFormName() {
|
||||||
|
@ -100,7 +100,7 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
/* 监听重新加载选项事件 */
|
/* 监听重新加载选项事件 */
|
||||||
this.$on('reloadOptions', function (widgetNames) {
|
this.$on('reloadOptionItems', function (widgetNames) {
|
||||||
if ((widgetNames.length === 0) || (widgetNames.indexOf(this.field.options.name) > -1)) {
|
if ((widgetNames.length === 0) || (widgetNames.indexOf(this.field.options.name) > -1)) {
|
||||||
this.initOptionItems(true)
|
this.initOptionItems(true)
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,10 @@ export default {
|
||||||
|| (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)) {
|
||||||
if (!!keepSelected) {
|
if (!!keepSelected) {
|
||||||
this.reloadOptions(this.globalOptionData[this.field.options.name])
|
//this.reloadOptions(this.globalOptionData[this.field.options.name]) /* 异步更新option-data之后不能获取到最新值,
|
||||||
|
// 以下改用provide的getOptionData()方法 */
|
||||||
|
const newOptionItems = this.getOptionData()
|
||||||
|
this.reloadOptions(newOptionItems[this.field.options.name])
|
||||||
} else {
|
} else {
|
||||||
this.loadOptions( this.globalOptionData[this.field.options.name] )
|
this.loadOptions( this.globalOptionData[this.field.options.name] )
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
refList: this.widgetRefList,
|
refList: this.widgetRefList,
|
||||||
formConfig: this.formConfig,
|
formConfig: this.formConfig,
|
||||||
globalOptionData: this.optionData,
|
globalOptionData: this.optionData,
|
||||||
|
getOptionData: () => this.optionData,
|
||||||
globalModel: {
|
globalModel: {
|
||||||
formModel: this.formModel,
|
formModel: this.formModel,
|
||||||
}
|
}
|
||||||
|
@ -222,7 +223,7 @@
|
||||||
|
|
||||||
.el-form.Pad-layout {
|
.el-form.Pad-layout {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 960px;
|
max-width: 960px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
box-shadow: 0 0 1px 10px #495060;
|
box-shadow: 0 0 1px 10px #495060;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,17 @@
|
||||||
<img src="../../assets/vform-logo.png" @click="openHome">
|
<img src="../../assets/vform-logo.png" @click="openHome">
|
||||||
<span class="bold">VForm</span> {{i18nt('application.productTitle')}} <span class="version-span">Ver {{vFormVersion}}</span></div>
|
<span class="bold">VForm</span> {{i18nt('application.productTitle')}} <span class="version-span">Ver {{vFormVersion}}</span></div>
|
||||||
<div class="float-right external-link">
|
<div class="float-right external-link">
|
||||||
<el-dropdown @command="handleLanguageChanged">
|
<el-dropdown v-if="showLink('languageMenu')" @command="handleLanguageChanged">
|
||||||
<span class="el-dropdown-link">{{curLangName}}<i class="el-icon-arrow-down el-icon--right"></i></span>
|
<span class="el-dropdown-link">{{curLangName}}<i class="el-icon-arrow-down el-icon--right"></i></span>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item command="zh-CN">{{i18nt('application.zh-CN')}}</el-dropdown-item>
|
<el-dropdown-item command="zh-CN">{{i18nt('application.zh-CN')}}</el-dropdown-item>
|
||||||
<el-dropdown-item command="en-US">{{i18nt('application.en-US')}}</el-dropdown-item>
|
<el-dropdown-item command="en-US">{{i18nt('application.en-US')}}</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<a href="javascript:void(0)" @click="(ev) => openUrl(ev, gitUrl)" target="_blank"><svg-icon icon-class="github" />{{i18nt('application.github')}}</a>
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, gitUrl)" target="_blank"><svg-icon icon-class="github" />{{i18nt('application.github')}}</a>
|
||||||
<a href="javascript:void(0)" @click="(ev) => openUrl(ev, docUrl)" target="_blank"><svg-icon icon-class="document" />{{i18nt('application.document')}}</a>
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, docUrl)" target="_blank"><svg-icon icon-class="document" />{{i18nt('application.document')}}</a>
|
||||||
<a href="javascript:void(0)" @click="(ev) => openUrl(ev, chatUrl)" target="_blank">{{i18nt('application.qqGroup')}}</a>
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, chatUrl)" target="_blank">{{i18nt('application.qqGroup')}}</a>
|
||||||
<a href="javascript:void(0)" @click="(ev) => openUrl(ev, subScribeUrl)" target="_blank">
|
<a v-if="showLink('externalLink')" href="javascript:void(0)" @click="(ev) => openUrl(ev, subScribeUrl)" target="_blank">
|
||||||
{{i18nt('application.subscription')}}<i class="el-icon-top-right"></i></a>
|
{{i18nt('application.subscription')}}<i class="el-icon-top-right"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
|
@ -37,7 +37,9 @@
|
||||||
|
|
||||||
<el-container class="center-layout-container">
|
<el-container class="center-layout-container">
|
||||||
<el-header class="toolbar-header">
|
<el-header class="toolbar-header">
|
||||||
<toolbar-panel :designer="designer"></toolbar-panel>
|
<toolbar-panel :designer="designer" ref="toolbarRef">
|
||||||
|
<template #toolButton><slot name="customToolButtons"></slot></template>
|
||||||
|
</toolbar-panel>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main class="form-widget-main">
|
<el-main class="form-widget-main">
|
||||||
<el-scrollbar class="container-scroll-bar" :style="{height: scrollerHeight}">
|
<el-scrollbar class="container-scroll-bar" :style="{height: scrollerHeight}">
|
||||||
|
@ -76,10 +78,36 @@
|
||||||
VFormWidget,
|
VFormWidget,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/* 后端字段列表API */
|
||||||
fieldListApi: {
|
fieldListApi: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/* 禁止显示的组件名称数组 */
|
||||||
|
bannedWidgets: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
|
||||||
|
designerConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
languageMenu: true, //是否显示语言切换菜单
|
||||||
|
externalLink: true, //是否显示GitHub、文档等外部链接
|
||||||
|
formTemplates: true, //是否显示表单模板
|
||||||
|
eventCollapse: true, //是否显示组件事件属性折叠面板
|
||||||
|
clearDesignerButton: true, //是否显示清空设计器按钮
|
||||||
|
previewFormButton: true, //是否显示预览表单按钮
|
||||||
|
importJsonButton: true, //是否显示导入JSON按钮
|
||||||
|
exportJsonButton: true, //是否显示导出JSON器按钮
|
||||||
|
exportCodeButton: true, //是否显示导出代码按钮
|
||||||
|
generateSFCButton: true, //是否显示生成SFC按钮
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -104,6 +132,8 @@
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
serverFieldList: this.fieldList,
|
serverFieldList: this.fieldList,
|
||||||
|
getDesignerConfig: () => this.designerConfig,
|
||||||
|
getBannedWidgets: () => this.bannedWidgets,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -125,6 +155,14 @@
|
||||||
this.loadFieldListFromServer()
|
this.loadFieldListFromServer()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showLink(configName) {
|
||||||
|
if (this.designerConfig[configName] === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.designerConfig[configName]
|
||||||
|
},
|
||||||
|
|
||||||
openHome() {
|
openHome() {
|
||||||
if (!!this.vsCodeFlag) {
|
if (!!this.vsCodeFlag) {
|
||||||
const msgObj = {
|
const msgObj = {
|
||||||
|
@ -233,6 +271,57 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearDesigner() {
|
||||||
|
this.$refs.toolbarRef.clearFormWidget()
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新表单设计器
|
||||||
|
*/
|
||||||
|
refreshDesigner() {
|
||||||
|
//this.designer.loadFormJson( this.getFormJson() ) //只有第一次调用生效??
|
||||||
|
|
||||||
|
let fJson = this.getFormJson()
|
||||||
|
this.designer.clearDesigner(true) //不触发历史记录变更
|
||||||
|
this.designer.loadFormJson(fJson)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览表单
|
||||||
|
*/
|
||||||
|
previewForm() {
|
||||||
|
this.$refs.toolbarRef.previewForm()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入表单JSON
|
||||||
|
*/
|
||||||
|
importJson() {
|
||||||
|
this.$refs.toolbarRef.importJson()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出表单JSON
|
||||||
|
*/
|
||||||
|
exportJson() {
|
||||||
|
this.$refs.toolbarRef.exportJson()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出Vue/HTML代码
|
||||||
|
*/
|
||||||
|
exportCode() {
|
||||||
|
this.$refs.toolbarRef.exportCode()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成SFC代码
|
||||||
|
*/
|
||||||
|
generateSFC() {
|
||||||
|
this.$refs.toolbarRef.generateSFC()
|
||||||
|
},
|
||||||
|
|
||||||
//TODO: 增加更多方法!!
|
//TODO: 增加更多方法!!
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
|
||||||
<el-collapse-item name="2" :title="i18nt('designer.setting.eventSetting')">
|
<el-collapse-item v-if="showEventCollapse()" name="2" :title="i18nt('designer.setting.eventSetting')">
|
||||||
<el-form-item label="onFormCreated" label-width="150px">
|
<el-form-item label="onFormCreated" label-width="150px">
|
||||||
<el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormCreated')">
|
<el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormCreated')">
|
||||||
{{i18nt('designer.setting.addEventHandler')}}</el-button>
|
{{i18nt('designer.setting.addEventHandler')}}</el-button>
|
||||||
|
@ -136,8 +136,11 @@
|
||||||
designer: Object,
|
designer: Object,
|
||||||
formConfig: Object,
|
formConfig: Object,
|
||||||
},
|
},
|
||||||
|
inject: ['getDesignerConfig'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
designerConfig: this.getDesignerConfig(),
|
||||||
|
|
||||||
formActiveCollapseNames: ['1', '2'],
|
formActiveCollapseNames: ['1', '2'],
|
||||||
|
|
||||||
formSizes: [
|
formSizes: [
|
||||||
|
@ -188,6 +191,14 @@
|
||||||
}, 1200)
|
}, 1200)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showEventCollapse() {
|
||||||
|
if (this.designerConfig['eventCollapse'] === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.designerConfig['eventCollapse']
|
||||||
|
},
|
||||||
|
|
||||||
editFormCss() {
|
editFormCss() {
|
||||||
this.formCssCode = this.designer.formConfig.cssCode
|
this.formCssCode = this.designer.formConfig.cssCode
|
||||||
this.showEditFormCssDialogFlag = true
|
this.showEditFormCssDialogFlag = true
|
||||||
|
|
|
@ -8,21 +8,21 @@
|
||||||
<el-form :model="optionModel" size="mini" label-position="left" label-width="120px" class="setting-form"
|
<el-form :model="optionModel" size="mini" label-position="left" label-width="120px" class="setting-form"
|
||||||
@submit.native.prevent>
|
@submit.native.prevent>
|
||||||
<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
|
<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
|
||||||
<el-collapse-item name="1" :title="i18nt('designer.setting.commonSetting')">
|
<el-collapse-item name="1" v-if="showCollapse(commonProps)" :title="i18nt('designer.setting.commonSetting')">
|
||||||
<template v-for="(editorName, propName) in commonProps">
|
<template v-for="(editorName, propName) in commonProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
</template>
|
</template>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
|
||||||
<el-collapse-item name="2" :title="i18nt('designer.setting.advancedSetting')">
|
<el-collapse-item name="2" v-if="showCollapse(advProps)" :title="i18nt('designer.setting.advancedSetting')">
|
||||||
<template v-for="(editorName, propName) in advProps">
|
<template v-for="(editorName, propName) in advProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
</template>
|
</template>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
|
||||||
<el-collapse-item name="3" :title="i18nt('designer.setting.eventSetting')">
|
<el-collapse-item name="3" v-if="showEventCollapse() && showCollapse(eventProps)" :title="i18nt('designer.setting.eventSetting')">
|
||||||
<template v-for="(editorName, propName) in eventProps">
|
<template v-for="(editorName, propName) in eventProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
|
@ -37,21 +37,21 @@
|
||||||
<el-form :model="optionModel" size="mini" label-position="left" label-width="120px" class="setting-form"
|
<el-form :model="optionModel" size="mini" label-position="left" label-width="120px" class="setting-form"
|
||||||
@submit.native.prevent>
|
@submit.native.prevent>
|
||||||
<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
|
<el-collapse v-model="widgetActiveCollapseNames" class="setting-collapse">
|
||||||
<el-collapse-item name="1" :title="i18nt('designer.setting.commonSetting')">
|
<el-collapse-item name="1" v-if="showCollapse(commonProps)" :title="i18nt('designer.setting.commonSetting')">
|
||||||
<template v-for="(editorName, propName) in commonProps">
|
<template v-for="(editorName, propName) in commonProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
</template>
|
</template>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
|
||||||
<el-collapse-item name="2" :title="i18nt('designer.setting.advancedSetting')">
|
<el-collapse-item name="2" v-if="showCollapse(advProps)" :title="i18nt('designer.setting.advancedSetting')">
|
||||||
<template v-for="(editorName, propName) in advProps">
|
<template v-for="(editorName, propName) in advProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
</template>
|
</template>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
|
||||||
<el-collapse-item name="3" :title="i18nt('designer.setting.eventSetting')">
|
<el-collapse-item name="3" v-if="showEventCollapse() && showCollapse(eventProps)" :title="i18nt('designer.setting.eventSetting')">
|
||||||
<template v-for="(editorName, propName) in eventProps">
|
<template v-for="(editorName, propName) in eventProps">
|
||||||
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
<component v-if="hasPropEditor(propName, editorName)" :is="getPropEditor(propName, editorName)"
|
||||||
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
:designer="designer" :selected-widget="selectedWidget" :option-model="optionModel"></component>
|
||||||
|
@ -114,8 +114,11 @@
|
||||||
selectedWidget: Object,
|
selectedWidget: Object,
|
||||||
formConfig: Object,
|
formConfig: Object,
|
||||||
},
|
},
|
||||||
|
inject: ['getDesignerConfig'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
designerConfig: this.getDesignerConfig(),
|
||||||
|
|
||||||
scrollerHeight: 0,
|
scrollerHeight: 0,
|
||||||
|
|
||||||
activeTab: "2",
|
activeTab: "2",
|
||||||
|
@ -195,6 +198,14 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showEventCollapse() {
|
||||||
|
if (this.designerConfig['eventCollapse'] === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.designerConfig['eventCollapse']
|
||||||
|
},
|
||||||
|
|
||||||
hasPropEditor(propName, editorName) {
|
hasPropEditor(propName, editorName) {
|
||||||
if (!editorName) {
|
if (!editorName) {
|
||||||
return false
|
return false
|
||||||
|
@ -215,6 +226,23 @@
|
||||||
return !!this.$root.$options.components[ownPropEditorName] ? ownPropEditorName : editorName //全局注册的属性编辑器组件
|
return !!this.$root.$options.components[ownPropEditorName] ? ownPropEditorName : editorName //全局注册的属性编辑器组件
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showCollapse(propsObj) {
|
||||||
|
let result = false
|
||||||
|
|
||||||
|
for (let propName in propsObj) {
|
||||||
|
if (!propsObj.hasOwnProperty(propName)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.hasPropEditor(propName, propsObj[propName])) {
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
},
|
||||||
|
|
||||||
editEventHandler(eventName, eventParams) {
|
editEventHandler(eventName, eventParams) {
|
||||||
this.curEventName = eventName
|
this.curEventName = eventName
|
||||||
this.eventHeader = `${this.optionModel.name}.${eventName}(${eventParams.join(', ')}) {`
|
this.eventHeader = `${this.optionModel.name}.${eventName}(${eventParams.join(', ')}) {`
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form-item :label="i18nt('designer.setting.gridColHeight')">
|
||||||
|
<el-input type="number" v-model="optionModel.colHeight" @input.native="inputNumberHandler"
|
||||||
|
min="0" class="hide-spin-button"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import i18n from "@/utils/i18n"
|
||||||
|
import propertyMixin from "@/components/form-designer/setting-panel/property-editor/propertyMixin"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "colHeight-editor",
|
||||||
|
mixins: [i18n, propertyMixin],
|
||||||
|
props: {
|
||||||
|
designer: Object,
|
||||||
|
selectedWidget: Object,
|
||||||
|
optionModel: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,7 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<el-input-number v-model="optionModel.defaultValue" :min="0" :max="optionModel.max" style="width: 100%"
|
<el-form-item :label="i18nt('designer.setting.defaultValue')">
|
||||||
@change="emitDefaultValueChange">
|
<el-input-number v-model="optionModel.defaultValue" :min="0" :max="optionModel.max" style="width: 100%"
|
||||||
</el-input-number>
|
@change="emitDefaultValueChange">
|
||||||
|
</el-input-number>
|
||||||
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -57,6 +57,7 @@ const COMMON_PROPERTIES = {
|
||||||
'showRowNumber' : 'showRowNumber-editor',
|
'showRowNumber' : 'showRowNumber-editor',
|
||||||
'cellWidth' : 'cellWidth-editor',
|
'cellWidth' : 'cellWidth-editor',
|
||||||
'cellHeight' : 'cellHeight-editor',
|
'cellHeight' : 'cellHeight-editor',
|
||||||
|
'colHeight' : 'colHeight-editor',
|
||||||
'gutter' : 'gutter-editor',
|
'gutter' : 'gutter-editor',
|
||||||
'responsive' : 'responsive-editor',
|
'responsive' : 'responsive-editor',
|
||||||
'span' : 'span-editor',
|
'span' : 'span-editor',
|
||||||
|
|
|
@ -13,15 +13,30 @@
|
||||||
<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>
|
||||||
|
<el-button type="" style="margin-left: 20px" :title="i18nt('designer.toolbar.nodeTreeHint')" @click="showNodeTreeDrawer">
|
||||||
|
<svg-icon icon-class="node-tree" /></el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-drawer :title="i18nt('designer.toolbar.nodeTreeTitle')" direction="ltr" :visible.sync="showNodeTreeDrawerFlag" :modal="false" :size="280"
|
||||||
|
:destroy-on-close="true" class="node-tree-drawer">
|
||||||
|
<el-tree ref="nodeTree" :data="nodeTreeData" node-key="id" default-expand-all highlight-current class="node-tree"
|
||||||
|
icon-class="el-icon-arrow-right" @node-click="onNodeTreeClick"></el-tree>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
<div class="right-toolbar">
|
<div class="right-toolbar">
|
||||||
<el-button type="text" @click="clearFormWidget"><i class="el-icon-delete" />{{i18nt('designer.toolbar.clear')}}</el-button>
|
<el-button v-if="showToolButton('clearDesignerButton')" type="text" @click="clearFormWidget">
|
||||||
<el-button type="text" @click="previewForm"><i class="el-icon-view" />{{i18nt('designer.toolbar.preview')}}</el-button>
|
<i class="el-icon-delete" />{{i18nt('designer.toolbar.clear')}}</el-button>
|
||||||
<el-button type="text" @click="importJson">{{i18nt('designer.toolbar.importJson')}}</el-button>
|
<el-button v-if="showToolButton('previewFormButton')" type="text" @click="previewForm">
|
||||||
<el-button type="text" @click="exportJson">{{i18nt('designer.toolbar.exportJson')}}</el-button>
|
<i class="el-icon-view" />{{i18nt('designer.toolbar.preview')}}</el-button>
|
||||||
<el-button type="text" @click="exportCode">{{i18nt('designer.toolbar.exportCode')}}</el-button>
|
<el-button v-if="showToolButton('importJsonButton')" type="text" @click="importJson">
|
||||||
<el-button type="text" @click="generateSFC"><svg-icon icon-class="vue-sfc" />{{i18nt('designer.toolbar.generateSFC')}}</el-button>
|
{{i18nt('designer.toolbar.importJson')}}</el-button>
|
||||||
|
<el-button v-if="showToolButton('exportJsonButton')" type="text" @click="exportJson">
|
||||||
|
{{i18nt('designer.toolbar.exportJson')}}</el-button>
|
||||||
|
<el-button v-if="showToolButton('exportCodeButton')" type="text" @click="exportCode">
|
||||||
|
{{i18nt('designer.toolbar.exportCode')}}</el-button>
|
||||||
|
<el-button v-if="showToolButton('generateSFCButton')" type="text" @click="generateSFC">
|
||||||
|
<svg-icon icon-class="vue-sfc" />{{i18nt('designer.toolbar.generateSFC')}}</el-button>
|
||||||
|
<slot name="toolButton"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog :title="i18nt('designer.toolbar.preview')" :visible.sync="showPreviewDialogFlag" v-if="showPreviewDialogFlag"
|
<el-dialog :title="i18nt('designer.toolbar.preview')" :visible.sync="showPreviewDialogFlag" v-if="showPreviewDialogFlag"
|
||||||
|
@ -29,7 +44,8 @@
|
||||||
:destroy-on-close="true" class="small-padding-dialog" width="75%" :fullscreen="layoutType === 'H5'">
|
:destroy-on-close="true" class="small-padding-dialog" width="75%" :fullscreen="layoutType === 'H5'">
|
||||||
<div>
|
<div>
|
||||||
<div class="form-render-wrapper" :class="[layoutType === 'H5' ? 'h5-layout' : '']">
|
<div class="form-render-wrapper" :class="[layoutType === 'H5' ? 'h5-layout' : '']">
|
||||||
<VFormRender ref="preForm" :form-json="formJson" :form-data="testFormData"
|
<VFormRender ref="preForm" :form-json="formJson" :form-data="testFormData" :preview-state="true"
|
||||||
|
:option-data="testOptionData"
|
||||||
@appendButtonClick="testOnAppendButtonClick" @buttonClick="testOnButtonClick"
|
@appendButtonClick="testOnAppendButtonClick" @buttonClick="testOnButtonClick"
|
||||||
@formChange="handleFormChange"></VFormRender>
|
@formChange="handleFormChange"></VFormRender>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,12 +154,19 @@
|
||||||
import VFormRender from '@/components/form-render/index'
|
import VFormRender from '@/components/form-render/index'
|
||||||
import CodeEditor from '@/components/code-editor/index'
|
import CodeEditor from '@/components/code-editor/index'
|
||||||
import Clipboard from 'clipboard'
|
import Clipboard from 'clipboard'
|
||||||
import {deepClone, copyToClipboard, generateId, getQueryParam} from "@/utils/util";
|
import {
|
||||||
|
deepClone,
|
||||||
|
copyToClipboard,
|
||||||
|
generateId,
|
||||||
|
getQueryParam,
|
||||||
|
traverseAllWidgets
|
||||||
|
} from "@/utils/util";
|
||||||
import i18n from '@/utils/i18n'
|
import i18n from '@/utils/i18n'
|
||||||
import {generateCode} from "@/utils/code-generator";
|
import {generateCode} from "@/utils/code-generator";
|
||||||
import {genSFC} from "@/utils/sfc-generator";
|
import {genSFC} from "@/utils/sfc-generator";
|
||||||
import loadBeautifier from "@/utils/beautifierLoader";
|
import loadBeautifier from "@/utils/beautifierLoader";
|
||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ToolbarPanel",
|
name: "ToolbarPanel",
|
||||||
|
@ -156,14 +179,20 @@
|
||||||
props: {
|
props: {
|
||||||
designer: Object
|
designer: Object
|
||||||
},
|
},
|
||||||
|
inject: ['getDesignerConfig'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
designerConfig: this.getDesignerConfig(),
|
||||||
|
|
||||||
showPreviewDialogFlag: false,
|
showPreviewDialogFlag: false,
|
||||||
showImportJsonDialogFlag: false,
|
showImportJsonDialogFlag: false,
|
||||||
showExportJsonDialogFlag: false,
|
showExportJsonDialogFlag: false,
|
||||||
showExportCodeDialogFlag: false,
|
showExportCodeDialogFlag: false,
|
||||||
showFormDataDialogFlag: false,
|
showFormDataDialogFlag: false,
|
||||||
showExportSFCDialogFlag: false,
|
showExportSFCDialogFlag: false,
|
||||||
|
showNodeTreeDrawerFlag: false,
|
||||||
|
|
||||||
|
nodeTreeData: [],
|
||||||
|
|
||||||
testFunc: '',
|
testFunc: '',
|
||||||
importTemplate: '',
|
importTemplate: '',
|
||||||
|
@ -188,7 +217,17 @@
|
||||||
// {'pName': 'iPhone12', 'pNum': 10},
|
// {'pName': 'iPhone12', 'pNum': 10},
|
||||||
// {'pName': 'P50', 'pNum': 16},
|
// {'pName': 'P50', 'pNum': 16},
|
||||||
// ]
|
// ]
|
||||||
|
|
||||||
|
'select62173': 2,
|
||||||
},
|
},
|
||||||
|
testOptionData: {
|
||||||
|
'select62173': [
|
||||||
|
{label: '01', value: 1},
|
||||||
|
{label: '22', value: 2},
|
||||||
|
{label: '333', value: 3},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -211,8 +250,122 @@
|
||||||
return this.designer.getLayoutType()
|
return this.designer.getLayoutType()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'designer.widgetList': {
|
||||||
|
deep: true,
|
||||||
|
handler(val) {
|
||||||
|
//console.log('test-----', val)
|
||||||
|
//this.refreshNodeTree()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showToolButton(configName) {
|
||||||
|
if (this.designerConfig[configName] === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.designerConfig[configName]
|
||||||
|
},
|
||||||
|
|
||||||
|
buildTreeNodeOfWidget(widget, treeNode) {
|
||||||
|
let curNode = {
|
||||||
|
id: widget.id,
|
||||||
|
label: widget.options.label || widget.type,
|
||||||
|
//selectable: true,
|
||||||
|
}
|
||||||
|
treeNode.push(curNode)
|
||||||
|
|
||||||
|
if (widget.category === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
curNode.children = []
|
||||||
|
if (widget.type === 'grid') {
|
||||||
|
widget.cols.map(col => {
|
||||||
|
let colNode = {
|
||||||
|
id: col.id,
|
||||||
|
label: col.options.name || widget.type,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
curNode.children.push(colNode)
|
||||||
|
col.widgetList.map(wChild => {
|
||||||
|
this.buildTreeNodeOfWidget(wChild, colNode.children)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (widget.type === 'table') {
|
||||||
|
//TODO: 需要考虑合并单元格!!
|
||||||
|
widget.rows.map(row => {
|
||||||
|
let rowNode = {
|
||||||
|
id: row.id,
|
||||||
|
label: 'table-row',
|
||||||
|
selectable: false,
|
||||||
|
children: [],
|
||||||
|
}
|
||||||
|
curNode.children.push(rowNode)
|
||||||
|
|
||||||
|
row.cols.map(cell => {
|
||||||
|
if (!!cell.merged) { //跳过合并单元格!!
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let rowChildren = rowNode.children
|
||||||
|
let cellNode = {
|
||||||
|
id: cell.id,
|
||||||
|
label: 'table-cell',
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
rowChildren.push(cellNode)
|
||||||
|
|
||||||
|
cell.widgetList.map(wChild => {
|
||||||
|
this.buildTreeNodeOfWidget(wChild, cellNode.children)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (widget.type === 'tab') {
|
||||||
|
widget.tabs.map(tab => {
|
||||||
|
let tabNode = {
|
||||||
|
id: tab.id,
|
||||||
|
label: tab.options.name || widget.type,
|
||||||
|
selectable: false,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
curNode.children.push(tabNode)
|
||||||
|
tab.widgetList.map(wChild => {
|
||||||
|
this.buildTreeNodeOfWidget(wChild, tabNode.children)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (widget.type === 'sub-form') {
|
||||||
|
widget.widgetList.map(wChild => {
|
||||||
|
this.buildTreeNodeOfWidget(wChild, curNode.children)
|
||||||
|
})
|
||||||
|
} else if (widget.category === 'container') { //自定义容器
|
||||||
|
widget.widgetList.map(wChild => {
|
||||||
|
this.buildTreeNodeOfWidget(wChild, curNode.children)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
refreshNodeTree() {
|
||||||
|
this.nodeTreeData.length = 0
|
||||||
|
this.designer.widgetList.forEach(wItem => {
|
||||||
|
this.buildTreeNodeOfWidget(wItem, this.nodeTreeData)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
showNodeTreeDrawer() {
|
||||||
|
this.refreshNodeTree()
|
||||||
|
this.showNodeTreeDrawerFlag = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (!!this.designer.selectedId) { //同步当前选中组件到节点树!!!
|
||||||
|
this.$refs.nodeTree.setCurrentKey(this.designer.selectedId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
undoHistory() {
|
undoHistory() {
|
||||||
this.designer.undoHistoryStep()
|
this.designer.undoHistoryStep()
|
||||||
},
|
},
|
||||||
|
@ -405,12 +558,14 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
handleFormChange(fieldName, newValue, oldValue, formModel) {
|
handleFormChange(fieldName, newValue, oldValue, formModel) {
|
||||||
|
/*
|
||||||
console.log('---formChange start---')
|
console.log('---formChange start---')
|
||||||
console.log('fieldName', fieldName)
|
console.log('fieldName', fieldName)
|
||||||
console.log('newValue', newValue)
|
console.log('newValue', newValue)
|
||||||
console.log('oldValue', oldValue)
|
console.log('oldValue', oldValue)
|
||||||
console.log('formModel', formModel)
|
console.log('formModel', formModel)
|
||||||
console.log('---formChange end---')
|
console.log('---formChange end---')
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
|
|
||||||
testOnAppendButtonClick(clickedWidget) {
|
testOnAppendButtonClick(clickedWidget) {
|
||||||
|
@ -421,6 +576,31 @@
|
||||||
console.log('test', button)
|
console.log('test', button)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
findWidgetById(wId) {
|
||||||
|
let foundW = null
|
||||||
|
traverseAllWidgets(this.designer.widgetList, (w) => {
|
||||||
|
if (w.id === wId) {
|
||||||
|
foundW = w
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return foundW
|
||||||
|
},
|
||||||
|
|
||||||
|
onNodeTreeClick(nodeData, node, nodeEl) {
|
||||||
|
//console.log('test', JSON.stringify(nodeData))
|
||||||
|
|
||||||
|
if ((nodeData.selectable !== undefined) && !nodeData.selectable) {
|
||||||
|
this.$message.info(this.i18nt('designer.hint.currentNodeCannotBeSelected'))
|
||||||
|
} else {
|
||||||
|
const selectedId = nodeData.id
|
||||||
|
const foundW = this.findWidgetById(selectedId)
|
||||||
|
if (!!foundW) {
|
||||||
|
this.designer.setSelected(foundW)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -496,4 +676,106 @@
|
||||||
box-shadow: 0 0 1px 10px #495060;
|
box-shadow: 0 0 1px 10px #495060;
|
||||||
height: calc(100vh - 142px);
|
height: calc(100vh - 142px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node-tree-drawer ::v-deep {
|
||||||
|
.el-drawer {
|
||||||
|
padding: 15px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-drawer__header {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 5px 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.node-tree-scroll-bar {*/
|
||||||
|
/* height: 100%;*/
|
||||||
|
/* overflow: auto;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
.node-tree ::v-deep {
|
||||||
|
.el-tree > .el-tree-node:after {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.el-tree-node {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__content {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon.is-leaf{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.el-tree-node__children {
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node :last-child:before {
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree > .el-tree-node:before {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree > .el-tree-node:after {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node:before {
|
||||||
|
content: "";
|
||||||
|
left: -4px;
|
||||||
|
position: absolute;
|
||||||
|
right: auto;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node:after {
|
||||||
|
content: "";
|
||||||
|
left: -4px;
|
||||||
|
position: absolute;
|
||||||
|
right: auto;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node:before {
|
||||||
|
border-left: 1px dashed #4386c6;
|
||||||
|
bottom: 0px;
|
||||||
|
height: 100%;
|
||||||
|
top: -26px;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node:after {
|
||||||
|
border-top: 1px dashed #4386c6;
|
||||||
|
height: 20px;
|
||||||
|
top: 12px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node.is-current > .el-tree-node__content {
|
||||||
|
background: #c2d6ea !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon {
|
||||||
|
margin-left: -3px;
|
||||||
|
padding: 6px 6px 6px 0px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon.el-icon-caret-right:before {
|
||||||
|
//font-size: 16px;
|
||||||
|
//content: "\e723";
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon.expanded.el-icon-caret-right:before {
|
||||||
|
//font-size: 16px;
|
||||||
|
//content: "\e722";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -55,14 +55,14 @@
|
||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane name="formLib" style="padding: 8px">
|
<el-tab-pane v-if="showFormTemplates()" 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">
|
<template v-for="(ft, idx) in formTemplates">
|
||||||
<el-card :bord-style="{ padding: '0' }" shadow="hover" class="ft-card">
|
<el-card :bord-style="{ padding: '0' }" shadow="hover" class="ft-card">
|
||||||
<el-popover placement="right" trigger="hover">
|
<el-popover placement="right" trigger="hover">
|
||||||
<img slot="reference" :src="ft.imgUrl" style="width: 200px">
|
<img slot="reference" :src="ftImages[idx].imgUrl" style="width: 200px">
|
||||||
<img :src="ft.imgUrl" style="height: 600px;width: 720px">
|
<img :src="ftImages[idx].imgUrl" style="height: 600px;width: 720px">
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<div class="bottom clear-fix">
|
<div class="bottom clear-fix">
|
||||||
<span class="ft-title">#{{idx+1}} {{ft.title}}</span>
|
<span class="ft-title">#{{idx+1}} {{ft.title}}</span>
|
||||||
|
@ -87,6 +87,15 @@
|
||||||
import i18n from "@/utils/i18n"
|
import i18n from "@/utils/i18n"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
|
|
||||||
|
import ftImg1 from '@/assets/ft-images/t1.png'
|
||||||
|
import ftImg2 from '@/assets/ft-images/t2.png'
|
||||||
|
import ftImg3 from '@/assets/ft-images/t3.png'
|
||||||
|
import ftImg4 from '@/assets/ft-images/t4.png'
|
||||||
|
import ftImg5 from '@/assets/ft-images/t5.png'
|
||||||
|
import ftImg6 from '@/assets/ft-images/t6.png'
|
||||||
|
import ftImg7 from '@/assets/ft-images/t7.png'
|
||||||
|
import ftImg8 from '@/assets/ft-images/t8.png'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FieldPanel",
|
name: "FieldPanel",
|
||||||
mixins: [i18n],
|
mixins: [i18n],
|
||||||
|
@ -96,8 +105,11 @@
|
||||||
props: {
|
props: {
|
||||||
designer: Object,
|
designer: Object,
|
||||||
},
|
},
|
||||||
|
inject: ['getBannedWidgets', 'getDesignerConfig'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
designerConfig: this.getDesignerConfig(),
|
||||||
|
|
||||||
firstTab: 'componentLib',
|
firstTab: 'componentLib',
|
||||||
|
|
||||||
scrollerHeight: 0,
|
scrollerHeight: 0,
|
||||||
|
@ -110,6 +122,16 @@
|
||||||
customFields,
|
customFields,
|
||||||
|
|
||||||
formTemplates: formTemplates,
|
formTemplates: formTemplates,
|
||||||
|
ftImages: [
|
||||||
|
{imgUrl: ftImg1},
|
||||||
|
{imgUrl: ftImg2},
|
||||||
|
{imgUrl: ftImg3},
|
||||||
|
{imgUrl: ftImg4},
|
||||||
|
{imgUrl: ftImg5},
|
||||||
|
{imgUrl: ftImg6},
|
||||||
|
{imgUrl: ftImg7},
|
||||||
|
{imgUrl: ftImg8},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -127,6 +149,18 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
isBanned(wName) {
|
||||||
|
return this.getBannedWidgets().indexOf(wName) > -1
|
||||||
|
},
|
||||||
|
|
||||||
|
showFormTemplates() {
|
||||||
|
if (this.designerConfig['formTemplates'] === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.designerConfig['formTemplates']
|
||||||
|
},
|
||||||
|
|
||||||
loadWidgets() {
|
loadWidgets() {
|
||||||
this.containers = this.containers.map(con => {
|
this.containers = this.containers.map(con => {
|
||||||
return {
|
return {
|
||||||
|
@ -134,7 +168,7 @@
|
||||||
displayName: this.i18n2t(`designer.widgetLabel.${con.type}`, `extension.widgetLabel.${con.type}`)
|
displayName: this.i18n2t(`designer.widgetLabel.${con.type}`, `extension.widgetLabel.${con.type}`)
|
||||||
}
|
}
|
||||||
}).filter(con => {
|
}).filter(con => {
|
||||||
return !con.internal
|
return !con.internal && !this.isBanned(con.type)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.basicFields = this.basicFields.map(fld => {
|
this.basicFields = this.basicFields.map(fld => {
|
||||||
|
@ -142,6 +176,8 @@
|
||||||
...fld,
|
...fld,
|
||||||
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
||||||
}
|
}
|
||||||
|
}).filter(fld => {
|
||||||
|
return !this.isBanned(fld.type)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.advancedFields = this.advancedFields.map(fld => {
|
this.advancedFields = this.advancedFields.map(fld => {
|
||||||
|
@ -149,6 +185,8 @@
|
||||||
...fld,
|
...fld,
|
||||||
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
||||||
}
|
}
|
||||||
|
}).filter(fld => {
|
||||||
|
return !this.isBanned(fld.type)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.customFields = this.customFields.map(fld => {
|
this.customFields = this.customFields.map(fld => {
|
||||||
|
@ -156,6 +194,8 @@
|
||||||
...fld,
|
...fld,
|
||||||
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
||||||
}
|
}
|
||||||
|
}).filter(fld => {
|
||||||
|
return !this.isBanned(fld.type)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ export const containers = [
|
||||||
name: '',
|
name: '',
|
||||||
hidden: false,
|
hidden: false,
|
||||||
gutter: 12,
|
gutter: 12,
|
||||||
|
colHeight: null, //栅格列统一高度属性,用于解决栅格列设置响应式布局浮动后被挂住的问题!!
|
||||||
customClass: '', //自定义css类名
|
customClass: '', //自定义css类名
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-col class="grid-cell" :class="[customClass]" v-bind="layoutProps"
|
<el-col class="grid-cell" :class="[customClass]" v-bind="layoutProps" :style="colHeightStyle"
|
||||||
: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">
|
||||||
|
@ -38,6 +38,12 @@
|
||||||
parentWidget: Object,
|
parentWidget: Object,
|
||||||
parentList: Array,
|
parentList: Array,
|
||||||
indexOfParentList: Number,
|
indexOfParentList: Number,
|
||||||
|
|
||||||
|
colHeight: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
inject: ['refList', 'globalModel', 'formConfig', 'previewState'],
|
inject: ['refList', 'globalModel', 'formConfig', 'previewState'],
|
||||||
data() {
|
data() {
|
||||||
|
@ -58,6 +64,10 @@
|
||||||
return this.widget.options.customClass || ''
|
return this.widget.options.customClass || ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
colHeightStyle() {
|
||||||
|
return !!this.colHeight ? {height: this.colHeight + 'px'} : {}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initLayoutProps()
|
this.initLayoutProps()
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
:ref="widget.id" v-show="!widget.options.hidden">
|
:ref="widget.id" v-show="!widget.options.hidden">
|
||||||
<template v-for="(colWidget, colIdx) in widget.cols">
|
<template v-for="(colWidget, colIdx) in widget.cols">
|
||||||
<grid-col-item :widget="colWidget" :key="colIdx" :parent-list="widget.cols"
|
<grid-col-item :widget="colWidget" :key="colIdx" :parent-list="widget.cols"
|
||||||
:index-of-parent-list="colIdx" :parent-widget="widget"></grid-col-item>
|
:index-of-parent-list="colIdx" :parent-widget="widget"
|
||||||
|
:col-height="widget.options.colHeight"></grid-col-item>
|
||||||
</template>
|
</template>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
sfRefList: this.subFormRefList, //收集SubForm引用
|
sfRefList: this.subFormRefList, //收集SubForm引用
|
||||||
formConfig: this.formConfig,
|
formConfig: this.formConfig,
|
||||||
globalOptionData: this.optionData,
|
globalOptionData: this.optionData,
|
||||||
|
getOptionData: () => this.optionData, /* 该方法用于在异步更新option-data之后重新获取到最新值 */
|
||||||
globalModel: {
|
globalModel: {
|
||||||
formModel: this.formDataModel,
|
formModel: this.formDataModel,
|
||||||
},
|
},
|
||||||
|
@ -356,13 +357,15 @@
|
||||||
* @param widgetNames 指定重新加载的组件名称或组件名数组,不传则重新加载所有选项字段
|
* @param widgetNames 指定重新加载的组件名称或组件名数组,不传则重新加载所有选项字段
|
||||||
*/
|
*/
|
||||||
reloadOptionData(widgetNames) {
|
reloadOptionData(widgetNames) {
|
||||||
|
//this._provided.globalOptionData = this.optionData
|
||||||
|
|
||||||
let eventParams = []
|
let eventParams = []
|
||||||
if (!!widgetNames && (typeof widgetNames === 'string')) {
|
if (!!widgetNames && (typeof widgetNames === 'string')) {
|
||||||
eventParams = [widgetNames]
|
eventParams = [widgetNames]
|
||||||
} else if (!!widgetNames && Array.isArray(widgetNames)) {
|
} else if (!!widgetNames && Array.isArray(widgetNames)) {
|
||||||
eventParams = [...widgetNames]
|
eventParams = [...widgetNames]
|
||||||
}
|
}
|
||||||
this.broadcast('FieldWidget', 'reloadOptions', [eventParams])
|
this.broadcast('FieldWidget', 'reloadOptionItems', [eventParams])
|
||||||
},
|
},
|
||||||
|
|
||||||
getFormData(needValidation = true) {
|
getFormData(needValidation = true) {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1637920503900" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4875" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M332.48 500.864a25.6 25.6 0 1 0 0-51.2H192.384v-184.96a115.2 115.2 0 0 0 89.6-112.128c0-63.488-51.712-115.2-115.2-115.2s-115.2 51.712-115.2 115.2a115.2 115.2 0 0 0 89.6 112.128v696.192a25.6 25.6 0 1 0 51.2 0v-141.12c2.304 0.192 4.48 0.512 6.912 0.512h133.184a25.6 25.6 0 1 0 0-51.2H199.296c-3.456 0-5.504-0.448-6.08-0.256a29.184 29.184 0 0 1-0.896-8.576V500.8h140.16zM102.784 152.64c0-35.264 28.736-64 64-64s64 28.736 64 64-28.736 64-64 64-64-28.736-64-64zM921.216 360.064h-486.4c-28.224 0-51.2 22.976-51.2 51.2v128c0 28.224 22.976 51.2 51.2 51.2h486.4c28.224 0 51.2-22.976 51.2-51.2v-128c0-28.224-22.976-51.2-51.2-51.2z m-486.336 179.2v-128h486.4v128h-486.4zM921.216 679.616h-486.4c-28.224 0-51.2 22.976-51.2 51.2v128c0 28.224 22.976 51.2 51.2 51.2h486.4c28.224 0 51.2-22.976 51.2-51.2v-128c0-28.224-22.976-51.2-51.2-51.2z m-486.336 179.2v-128h486.4v128h-486.4z" p-id="4876"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -112,6 +112,7 @@ export default {
|
||||||
loadFormTemplateHint: 'Are you sure to load this template?',
|
loadFormTemplateHint: 'Are you sure to load this template?',
|
||||||
loadFormTemplateSuccess: 'Load form template success!',
|
loadFormTemplateSuccess: 'Load form template success!',
|
||||||
loadFormTemplateFailed: 'Load form template failed.',
|
loadFormTemplateFailed: 'Load form template failed.',
|
||||||
|
currentNodeCannotBeSelected: 'The current node cannot be selected.',
|
||||||
|
|
||||||
widgetSetting: 'Widget Config',
|
widgetSetting: 'Widget Config',
|
||||||
formSetting: 'Form Config',
|
formSetting: 'Form Config',
|
||||||
|
@ -147,6 +148,8 @@ export default {
|
||||||
pcLayout: 'PC',
|
pcLayout: 'PC',
|
||||||
padLayout: 'Pad',
|
padLayout: 'Pad',
|
||||||
mobileLayout: 'H5',
|
mobileLayout: 'H5',
|
||||||
|
nodeTreeHint: 'Tree View Of Component Hierarchy',
|
||||||
|
nodeTreeTitle: 'Tree View Of Component Hierarchy',
|
||||||
clear: 'Clear',
|
clear: 'Clear',
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
importJson: 'Import JSON',
|
importJson: 'Import JSON',
|
||||||
|
@ -223,6 +226,7 @@ export default {
|
||||||
|
|
||||||
cellWidth: 'Width',
|
cellWidth: 'Width',
|
||||||
cellHeight: 'Height',
|
cellHeight: 'Height',
|
||||||
|
gridColHeight: 'Height Of Col(px)',
|
||||||
gutter: 'Gutter(px)',
|
gutter: 'Gutter(px)',
|
||||||
columnSetting: 'Cols Setting',
|
columnSetting: 'Cols Setting',
|
||||||
colsOfGrid: 'Cols Of Grid:',
|
colsOfGrid: 'Cols Of Grid:',
|
||||||
|
|
|
@ -112,6 +112,7 @@ export default {
|
||||||
loadFormTemplateHint: '是否加载这个模板?加载后会覆盖设计器当前表单,你可以使用“撤销”功能恢复。',
|
loadFormTemplateHint: '是否加载这个模板?加载后会覆盖设计器当前表单,你可以使用“撤销”功能恢复。',
|
||||||
loadFormTemplateSuccess: '表单模板加载成功',
|
loadFormTemplateSuccess: '表单模板加载成功',
|
||||||
loadFormTemplateFailed: '表单模板加载失败',
|
loadFormTemplateFailed: '表单模板加载失败',
|
||||||
|
currentNodeCannotBeSelected: '当前组件节点不可选择',
|
||||||
|
|
||||||
widgetSetting: '组件设置',
|
widgetSetting: '组件设置',
|
||||||
formSetting: '表单设置',
|
formSetting: '表单设置',
|
||||||
|
@ -147,6 +148,8 @@ export default {
|
||||||
pcLayout: 'PC',
|
pcLayout: 'PC',
|
||||||
padLayout: 'Pad',
|
padLayout: 'Pad',
|
||||||
mobileLayout: 'H5',
|
mobileLayout: 'H5',
|
||||||
|
nodeTreeHint: '组件层次结构树',
|
||||||
|
nodeTreeTitle: '组件层次结构树',
|
||||||
clear: '清空',
|
clear: '清空',
|
||||||
preview: '预览',
|
preview: '预览',
|
||||||
importJson: '导入JSON',
|
importJson: '导入JSON',
|
||||||
|
@ -223,7 +226,8 @@ export default {
|
||||||
|
|
||||||
cellWidth: '宽度',
|
cellWidth: '宽度',
|
||||||
cellHeight: '高度',
|
cellHeight: '高度',
|
||||||
gutter: '栅格间隔(像素)',
|
gridColHeight: '栅格列统一高度(px)',
|
||||||
|
gutter: '栅格间隔(px)',
|
||||||
columnSetting: '栅格属性设置',
|
columnSetting: '栅格属性设置',
|
||||||
colsOfGrid: '当前栅格列:',
|
colsOfGrid: '当前栅格列:',
|
||||||
colSpanTitle: '栅格宽度',
|
colSpanTitle: '栅格宽度',
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const DESIGNER_OPTIONS = {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VARIANT_FORM_VERSION = '2.1.7'
|
export const VARIANT_FORM_VERSION = '2.1.8'
|
||||||
|
|
||||||
//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 MOCK_CASE_URL = 'https://ks3-cn-beijing.ksyuncs.com/vform-static/vcase/'
|
||||||
|
|
|
@ -172,6 +172,34 @@ export function traverseContainWidgets(widgetList, handler) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function traverseAllWidgets(widgetList, handler) {
|
||||||
|
widgetList.map(w => {
|
||||||
|
handler(w)
|
||||||
|
|
||||||
|
if (w.type === 'grid') {
|
||||||
|
w.cols.map(col => {
|
||||||
|
handler(col)
|
||||||
|
traverseAllWidgets(col.widgetList, handler)
|
||||||
|
})
|
||||||
|
} else if (w.type === 'table') {
|
||||||
|
w.rows.map(row => {
|
||||||
|
row.cols.map(cell => {
|
||||||
|
handler(cell)
|
||||||
|
traverseAllWidgets(cell.widgetList, handler)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (w.type === 'tab') {
|
||||||
|
w.tabs.map(tab => {
|
||||||
|
traverseAllWidgets(tab.widgetList, handler)
|
||||||
|
})
|
||||||
|
} else if (w.type === 'sub-form') {
|
||||||
|
traverseAllWidgets(w.widgetList, handler)
|
||||||
|
} else if (w.category === 'container') { //自定义容器
|
||||||
|
traverseAllWidgets(w.widgetList, handler)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function copyToClipboard(content, clickEvent, $message, successMsg, errorMsg) {
|
export function copyToClipboard(content, clickEvent, $message, successMsg, errorMsg) {
|
||||||
const clipboard = new Clipboard(clickEvent.target, {
|
const clipboard = new Clipboard(clickEvent.target, {
|
||||||
text: () => content
|
text: () => content
|
||||||
|
|