增加二次开发组件示例。

develop
vdpAdmin 2021-10-25 14:18:13 +08:00
parent 1439eb53d4
commit 9a7a2573ce
46 changed files with 1006 additions and 90 deletions

View File

@ -7,8 +7,8 @@
*/
import {deepClone, generateId, overwriteObj} from "@/utils/util"
import {advancedFields, basicFields, containers} from "@/components/form-designer/widget-panel/widgetsConfig.js";
import {VARIANT_FORM_VERSION} from "@/utils/config";
import {containers, advancedFields, basicFields, customFields} from "@/components/form-designer/widget-panel/widgetsConfig.js"
import {VARIANT_FORM_VERSION} from "@/utils/config"
export function createDesigner(vueInstance) {
let defaultFormConfig = {
@ -443,9 +443,10 @@ export function createDesigner(vueInstance) {
},
getContainerByType(typeName) {
let allWidgets = [...containers, ...basicFields, ...advancedFields, ...customFields]
let foundCon = null
containers.forEach(con => {
if (!!con.type && (con.type === typeName)) {
allWidgets.forEach(con => {
if (!!con.category && !!con.type && (con.type === typeName)) {
foundCon = con
}
})
@ -454,20 +455,11 @@ export function createDesigner(vueInstance) {
},
getFieldWidgetByType(typeName) {
let allWidgets = [...containers, ...basicFields, ...advancedFields, ...customFields]
let foundWidget = null
basicFields.forEach(bf => {
if (!!bf.type && (bf.type === typeName)) {
foundWidget = bf
}
})
if (!!foundWidget) {
return foundWidget
}
advancedFields.forEach(af => {
if (!!af.type && (af.type === typeName)) {
foundWidget = af
allWidgets.forEach(widget => {
if (!!!widget.category && !!widget.type && (widget.type === typeName)) {
foundWidget = widget
}
})

View File

@ -30,7 +30,8 @@
<div class="drag-handler" v-if="designer.selectedId === widget.id && !widget.internal">
<i class="el-icon-rank" :title="i18nt('designer.hint.dragHandler')"></i>
<i>{{i18nt('designer.widgetLabel.' + widget.type)}}</i>
<i>{{i18n2t(`designer.widgetLabel.${widget.type}`, `extension.widgetLabel.${widget.type}`)}}</i>
<i v-if="widget.options.hidden === true" class="iconfont icon-hide"></i>
</div>
</div>
</template>
@ -79,7 +80,7 @@
position: absolute;
top: -2px;
//bottom: -24px; /* */
left: -6px;
left: -2px;
height: 22px;
line-height: 22px;
background: $--color-primary;

View File

@ -1,5 +1,6 @@
<template>
<el-col v-else-if="widget.type === 'grid-col'" class="grid-cell" :span="widget.options.span || 12"
:offset="widget.options.offset || 0" :push="widget.options.push || 0" :pull="widget.options.pull || 0"
:class="[selected ? 'selected' : '', customClass]"
:key="widget.id" @click.native.stop="selectWidget(widget)">
<draggable :list="widget.widgetList" v-bind="{group:'dragGroup', ghostClass: 'ghost',animation: 200}"
@ -40,7 +41,6 @@
<script>
import Draggable from 'vuedraggable'
import i18n from "@/utils/i18n";
import ContainerComponents from '@/components/form-designer/form-widget/container-widget/index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
@ -49,7 +49,6 @@
mixins: [i18n],
components: {
Draggable,
...ContainerComponents,
...FieldComponents,
},
props: {
@ -150,11 +149,8 @@
<style lang="scss" scoped>
.grid-cell {
min-height: 38px;
//line-height: 36px;
margin: 6px 0;
//margin: 6px 0; /* marginoffsetpushpull */
padding: 3px;
//min-height: 300px;
//border-right: 1px dotted #cccccc;
outline: 1px dashed #336699;
position: relative;
@ -164,7 +160,6 @@
.grid-col-action{
position: absolute;
//bottom: -30px;
bottom: 0;
right: -2px;
height: 28px;
@ -183,7 +178,6 @@
.grid-col-handler {
position: absolute;
top: -2px;
//bottom: -24px; /* */
left: -2px;
height: 22px;
line-height: 22px;
@ -195,7 +189,7 @@
font-style: normal;
color: #fff;
margin: 4px;
cursor: default; //cursor: move;
cursor: default;
}
}
}

View File

@ -1,5 +1,11 @@
import Vue from 'vue'
const requireComponent = require.context('./', false, /\w+\.vue$/)
/**
* 容器组件时递归组件且内部可以嵌套其他容器局部注册会找不到组件必须注册为全局组件原因不明
* begin
*
let comps = {}
requireComponent.keys().map(fileName => {
@ -8,3 +14,11 @@ requireComponent.keys().map(fileName => {
})
export default comps;
end */
/* 全局注册!! */
requireComponent.keys().map(fileName => {
let comp = requireComponent(fileName).default;
Vue.component(comp.name, comp)
})

View File

@ -48,7 +48,6 @@
import i18n from "@/utils/i18n"
import containerMixin from "@/components/form-designer/form-widget/container-widget/containerMixin"
import ContainerWrapper from "@/components/form-designer/form-widget/container-widget/container-wrapper"
import ContainerComponents from '@/components/form-designer/form-widget/container-widget/index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
@ -59,7 +58,6 @@
ContainerWrapper,
Draggable,
...ContainerComponents,
...FieldComponents,
},
props: {

View File

@ -54,7 +54,6 @@
<script>
import Draggable from 'vuedraggable'
import i18n from "@/utils/i18n"
import ContainerComponents from '@/components/form-designer/form-widget/container-widget/index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
@ -63,7 +62,6 @@
mixins: [i18n],
components: {
Draggable,
...ContainerComponents,
...FieldComponents,
},
props: {

View File

@ -1,4 +1,5 @@
import {deepClone} from "@/utils/util";
import {deepClone} from "@/utils/util"
import FormValidators from '@/utils/validators'
export default {
inject: ['refList', 'formConfig', 'globalOptionData', 'globalModel'],

View File

@ -48,7 +48,7 @@
<div class="drag-handler background-opacity" v-if="designer.selectedId === field.id">
<i class="el-icon-rank" :title="i18nt('designer.hint.dragHandler')"></i>
<i>{{i18nt('designer.widgetLabel.' + field.type)}}</i>
<i>{{i18n2t(`designer.widgetLabel.${field.type}`, `extension.widgetLabel.${field.type}`)}}</i>
<i v-if="field.options.hidden === true" class="iconfont icon-hide"></i>
</div>
</template>

View File

@ -1,7 +1,7 @@
<template>
<div class="field-wrapper" :class="{'design-time-bottom-margin': !!this.designer}">
<div class="static-content-item" v-show="!field.options.hidden || (designState === true)"
:class="{'selected': selected}" @click.stop="selectField(field)">
:class="[selected ? 'selected' : '', customClass]" @click.stop="selectField(field)">
<slot></slot>
</div>
@ -17,7 +17,7 @@
<div class="drag-handler background-opacity" v-if="designer.selectedId === field.id">
<i class="el-icon-rank" :title="i18nt('designer.hint.dragHandler')"></i>
<i>{{i18nt('designer.widgetLabel.' + field.type)}}</i>
<i>{{i18n2t(`designer.widgetLabel.${field.type}`, `extension.widgetLabel.${field.type}`)}}</i>
<i v-if="field.options.hidden === true" class="iconfont icon-hide"></i>
</div>
</template>
@ -60,6 +60,10 @@
return !!this.designer && this.field.id === this.designer.selectedId
},
customClass() {
return !!this.field.options.customClass ? this.field.options.customClass.join(' ') : ''
},
},
methods: {

View File

@ -29,7 +29,7 @@
<script>
import Draggable from 'vuedraggable'
import ContainerComponents from '@/components/form-designer/form-widget/container-widget/index'
import '@/components/form-designer/form-widget/container-widget/index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
import i18n from "@/utils/i18n"
@ -40,7 +40,6 @@
components: {
Draggable,
...ContainerComponents,
...FieldComponents,
},
props: {

View File

@ -9,7 +9,7 @@
-->
<template>
<el-container class="full-height">
<el-container class="main-container full-height">
<el-header class="main-header">
<div class="float-left main-title">
<img src="../../assets/vform-logo.png" @click="openHome">
@ -267,9 +267,10 @@
}
.el-header.toolbar-header {
font-size: 14px;
border-bottom: 1px dotted #CCCCCC;
height: 42px !important;
line-height: 42px !important;
//line-height: 42px !important;
}
.el-aside.side-panel {

View File

@ -0,0 +1,173 @@
import {translate} from "@/utils/i18n"
import emitter from 'element-ui/lib/mixins/emitter'
export const createInputTextEditor = function (propName, propLabelKey) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-input type="text" v-model={this.optionModel[propName]} />
</el-form-item>
)
}
}
}
export const createInputNumberEditor = function (propName, propLabelKey) {
return {
props: {
optionModel: Object,
},
methods: {
updateValue(newValue) {
if ((newValue === undefined) || (newValue === null) || isNaN(newValue)) {
this.optionModel[propName] = null
} else {
this.optionModel[propName] = Number(newValue)
}
},
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-input-number type="text" v-model={this.optionModel[propName]}
onChange={this.updateValue} style="width: 100%" />
</el-form-item>
)
}
}
}
export const createBooleanEditor = function (propName, propLabelKey) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-checkbox v-model={this.optionModel[propName]} />
</el-form-item>
)
}
}
}
export const createCheckboxGroupEditor = function (propName, propLabelKey, configs) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-checkbox-group v-model={this.optionModel[propName]}>
{
configs.optionItems.map(item => {
return <el-checkbox label={item.value}>{item.label}</el-checkbox>
})
}
</el-checkbox-group>
</el-form-item>
)
}
}
}
export const createRadioGroupEditor = function (propName, propLabelKey, configs) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-radio-group v-model={this.optionModel[propName]}>
{
configs.optionItems.map(item => {
return <el-radio label={item.value}>{item.label}</el-radio>
})
}
</el-radio-group>
</el-form-item>
)
}
}
}
export const createRadioButtonGroupEditor = function (propName, propLabelKey, configs) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-radio-group v-model={this.optionModel[propName]}>
{
configs.optionItems.map(item => {
return <el-radio-button label={item.value}>{item.label}</el-radio-button>
})
}
</el-radio-group>
</el-form-item>
)
}
}
}
export const createSelectEditor = function (propName, propLabelKey, configs) {
return {
props: {
optionModel: Object,
},
render(h) {
return (
<el-form-item label={translate(propLabelKey)}>
<el-select v-model={this.optionModel[propName]}>
{
configs.optionItems.map(item => {
return <el-option label={item.label} value={item.value} />
})
}
</el-select>
</el-form-item>
)
}
}
}
export const createEventHandlerEditor = function (eventPropName, eventParams) {
return {
props: {
optionModel: Object,
},
mixins: [emitter],
methods: {
editEventHandler() {
this.dispatch('SettingPanel', 'editEventHandler', [eventPropName, [...eventParams]])
},
},
render(h) {
return (
<el-form-item label={eventPropName} label-width="150px">
<el-button type="info" icon="el-icon-edit" plain round onClick={this.editEventHandler}>
{translate('designer.setting.addEventHandler')}</el-button>
</el-form-item>
)
}
}
}
export const createEmptyEditor = function () {
return {
render() {
return <div style="display: none" />
}
}
}

View File

@ -0,0 +1,24 @@
<template>
<el-form-item :label="i18nt('designer.setting.colOffsetTitle')">
<el-input-number v-model.number="optionModel.offset" :min="0" :max="24"
style="width: 100%"></el-input-number>
</el-form-item>
</template>
<script>
import i18n from "@/utils/i18n";
export default {
name: "grid-col-offset-editor",
mixins: [i18n],
props: {
designer: Object,
selectedWidget: Object,
optionModel: Object,
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,24 @@
<template>
<el-form-item :label="i18nt('designer.setting.colPullTitle')">
<el-input-number v-model.number="optionModel.pull" :min="0" :max="24"
style="width: 100%"></el-input-number>
</el-form-item>
</template>
<script>
import i18n from "@/utils/i18n";
export default {
name: "grid-col-pull-editor",
mixins: [i18n],
props: {
designer: Object,
selectedWidget: Object,
optionModel: Object,
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,24 @@
<template>
<el-form-item :label="i18nt('designer.setting.colPushTitle')">
<el-input-number v-model.number="optionModel.push" :min="0" :max="24"
style="width: 100%"></el-input-number>
</el-form-item>
</template>
<script>
import i18n from "@/utils/i18n";
export default {
name: "grid-col-push-editor",
mixins: [i18n],
props: {
designer: Object,
selectedWidget: Object,
optionModel: Object,
},
}
</script>
<style scoped>
</style>

View File

@ -2,18 +2,11 @@ import emitter from 'element-ui/lib/mixins/emitter'
export default {
mixins: [emitter],
created() {
// this.$on('saveEventHandler', function (params) {
// //this.optionModel[eventName] = handlerCodes
// this.optionModel[params[0]] = params[1]
// })
},
created() {},
methods: {
editEventHandler(eventName, eventParams) {
this.dispatch('SettingPanel', 'editEventHandler', [eventName, [...eventParams]])
},
}
}

View File

@ -0,0 +1,23 @@
<template>
<el-form-item :label="i18nt('designer.setting.activeColor')">
<el-color-picker v-model="optionModel.activeColor"></el-color-picker>
</el-form-item>
</template>
<script>
import i18n from "@/utils/i18n"
export default {
name: "activeColor-editor",
mixins: [i18n],
props: {
designer: Object,
selectedWidget: Object,
optionModel: Object,
},
}
</script>
<style scoped>
</style>

View File

@ -1,6 +1,6 @@
<template>
<el-form-item :label="i18nt('designer.setting.activeColor')">
<el-color-picker v-model="optionModel.activeColor"></el-color-picker>
<el-form-item :label="i18nt('designer.setting.activeText')">
<el-input v-model="optionModel.activeText"></el-input>
</el-form-item>
</template>

View File

@ -0,0 +1,23 @@
<template>
<el-form-item :label="i18nt('designer.setting.inactiveText')">
<el-input v-model="optionModel.inactiveText"></el-input>
</el-form-item>
</template>
<script>
import i18n from "@/utils/i18n"
export default {
name: "inactiveText-editor",
mixins: [i18n],
props: {
designer: Object,
selectedWidget: Object,
optionModel: Object,
},
}
</script>
<style scoped>
</style>

View File

@ -1,6 +1,8 @@
<template>
<el-switch v-model="optionModel.defaultValue" @change="emitDefaultValueChange"
active-text="true" inactive-text="false"></el-switch>
<el-form-item :label="i18nt('designer.setting.defaultValue')">
<el-switch v-model="optionModel.defaultValue" @change="emitDefaultValueChange"
active-text="true" inactive-text="false"></el-switch>
</el-form-item>
</template>
<script>

View File

@ -1,5 +1,5 @@
<template>
<el-form-item :label="i18nt('designer.setting.fieldName')" :rules="nameRequiredRule">
<el-form-item :label="i18nt('designer.setting.uniqueName')" :rules="nameRequiredRule">
<el-input type="text" v-model="optionModel.name" @change="updateWidgetNameAndRef"></el-input>
</el-form-item>
</template>

View File

@ -1,7 +1,9 @@
import Vue from 'vue'
/**
* 格式说明属性名称==对应属性编辑器的组件名称
*/
let COMMON_PROPERTIES = {
const COMMON_PROPERTIES = {
//字段
'name' : 'name-editor',
'label' : 'label-editor',
@ -56,10 +58,13 @@ let COMMON_PROPERTIES = {
'cellHeight' : 'cellHeight-editor',
'gutter' : 'gutter-editor',
'span' : 'span-editor',
'offset' : 'offset-editor',
'push' : 'push-editor',
'pull' : 'pull-editor',
}
let ADVANCED_PROPERTIES = {
const ADVANCED_PROPERTIES = {
'min' : 'min-editor',
'max' : 'max-editor',
'precision' : 'precision-editor',
@ -95,7 +100,7 @@ let ADVANCED_PROPERTIES = {
}
let EVENT_PROPERTIES = {
const EVENT_PROPERTIES = {
//字段
'onCreated' : 'onCreated-editor',
'onMounted' : 'onMounted-editor',
@ -135,6 +140,21 @@ export function registerEventProperty(propName, propEditorName) {
EVENT_PROPERTIES[propName] = propEditorName
}
export function registerCPEditor(propName, propEditorName, editorComponent) {
Vue.component(propEditorName, editorComponent)
registerCommonProperty(propName, propEditorName)
}
export function registerAPEditor(propName, propEditorName, editorComponent) {
Vue.component(propEditorName, editorComponent)
registerAdvancedProperty(propName, propEditorName)
}
export function registerEPEditor(propName, propEditorName, editorComponent) {
Vue.component(propEditorName, editorComponent)
registerEventProperty(propName, propEditorName)
}
export default {
COMMON_PROPERTIES,
ADVANCED_PROPERTIES,

View File

@ -45,7 +45,7 @@
<el-dialog :title="i18nt('designer.toolbar.importJson')" :visible.sync="showImportJsonDialogFlag"
v-if="showImportJsonDialogFlag" :show-close="true" class="small-padding-dialog" center v-dialog-drag
:close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
<el-alert type="info" :title="i18nt('designer.hint.importJsonHint')" show-icon></el-alert>
<el-alert type="info" :title="i18nt('designer.hint.importJsonHint')" show-icon class="alert-padding"></el-alert>
<code-editor :mode="'json'" :readonly="false" v-model="importTemplate"></code-editor>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="doJsonImport">
@ -445,15 +445,15 @@
.small-padding-dialog {
::v-deep .el-dialog__header {
padding-top: 3px;
padding-bottom: 3px;
//padding-top: 3px;
//padding-bottom: 3px;
background: #f1f2f3;
}
::v-deep .el-dialog__body {
padding: 12px 15px 12px 15px;
.el-alert {
.el-alert.alert-padding {
padding: 0 10px;
}
}
@ -481,6 +481,7 @@
.form-render-wrapper {
//height: calc(100vh - 142px);
all: revert !important; /* 防止表单继承el-dialog等外部样式未生效原因不明 */
}
.form-render-wrapper.h5-layout {

View File

@ -9,7 +9,7 @@
:move="checkContainerMove" @end="onContainerDragEnd">
<li v-for="(ctn, index) in containers" :key="index" class="container-widget-item" :title="ctn.displayName"
@dblclick="addContainerByDbClick(ctn)">
<span><svg-icon :icon-class="ctn.icon" />{{i18nt(`designer.widgetLabel.${ctn.type}`)}}</span>
<span><svg-icon :icon-class="ctn.icon" />{{i18n2t(`designer.widgetLabel.${ctn.type}`, `extension.widgetLabel.${ctn.type}`)}}</span>
</li>
</draggable>
</el-collapse-item>
@ -19,7 +19,7 @@
:clone="handleFieldWidgetClone" ghost-class="ghost" :sort="false">
<li v-for="(fld, index) in basicFields" :key="index" class="field-widget-item" :title="fld.displayName"
@dblclick="addFieldByDbClick(fld)">
<span><svg-icon :icon-class="fld.icon" />{{i18nt(`designer.widgetLabel.${fld.type}`)}}</span>
<span><svg-icon :icon-class="fld.icon" />{{i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)}}</span>
</li>
</draggable>
</el-collapse-item>
@ -29,22 +29,23 @@
:clone="handleFieldWidgetClone" ghost-class="ghost" :sort="false">
<li v-for="(fld, index) in advancedFields" :key="index" class="field-widget-item" :title="fld.displayName"
@dblclick="addFieldByDbClick(fld)">
<span><svg-icon :icon-class="fld.icon" />{{i18nt(`designer.widgetLabel.${fld.type}`)}}</span>
<span><svg-icon :icon-class="fld.icon" />{{i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)}}</span>
</li>
</draggable>
</el-collapse-item>
<!--
<!-- -->
<el-collapse-item name="4" :title="i18nt('designer.customFieldTitle')">
<draggable tag="ul" :list="customFields" :group="{name: 'dragGroup', pull: 'clone', put: false}"
:clone="handleFieldWidgetClone" ghost-class="ghost" :sort="false">
<li v-for="(fld, index) in customFields" :key="index" class="field-widget-item" :title="fld.displayName"
@dblclick="addFieldByDbClick(fld)">
<span :title="fld.displayName"><svg-icon :icon-class="fld.icon" />{{i18nt(`designer.widgetLabel.${fld.type}`)}}</span>
<span>
<svg-icon :icon-class="fld.icon" />{{i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)}}</span>
</li>
</draggable>
</el-collapse-item>
-->
<!-- -->
</el-collapse>
@ -102,8 +103,7 @@
this.containers = this.containers.map(con => {
return {
...con,
//category: 'container',
displayName: this.i18nt(`designer.widgetLabel.${con.type}`)
displayName: this.i18n2t(`designer.widgetLabel.${con.type}`, `extension.widgetLabel.${con.type}`)
}
}).filter(con => {
return !con.internal
@ -112,25 +112,23 @@
this.basicFields = this.basicFields.map(fld => {
return {
...fld,
displayName: this.i18nt(`designer.widgetLabel.${fld.type}`)
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
}
})
this.advancedFields = this.advancedFields.map(fld => {
return {
...fld,
displayName: this.i18nt(`designer.widgetLabel.${fld.type}`)
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
}
})
///*
this.customFields = this.customFields.map(fld => {
return {
...fld,
displayName: this.i18nt(`designer.widgetLabel.${fld.type}`)
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
}
})
//*/
},
handleContainerWidgetClone(origin) {

View File

@ -62,6 +62,9 @@ export const containers = [
name: '',
hidden: false,
span: 12,
offset: 0,
push: 0,
pull: 0,
customClass: '', //自定义css类名
}
},
@ -99,6 +102,46 @@ export const containers = [
}
},
/*
{
type: 'data-table',
category: 'container',
icon: 'data-table',
options: {
name: '',
label: '',
hidden: false,
columns: {},
checkboxColumn: {
width: 45,
},
operationColumn: {
buttons: [
{label: 'Edit', name: '', type: '', plain: false, round: true, circle: false, disabled: false, hidden: false},
{label: 'View', name: '', type: '', plain: false, round: true, circle: false, disabled: false, hidden: false},
{label: 'Delete', name: '', type: '', plain: false, round: true, circle: false, disabled: false, hidden: false},
{label: 'More...', name: '', type: '', plain: false, round: true, circle: false, disabled: false, hidden: false},
]
},
size: 'medium',
height: '100%',
maxHeight: '1200px',
stripe: false,
border: false,
fit: true,
highlightCurrentRow: false,
emptyText: 'no data',
showHeader: true,
showCheckBox: true,
showPager: false,
pagerPosition: 'center',
pagerSmall: false,
pagerBackground: false,
pagerCount: 7,
}
}
*/
]
export const basicFields = [
@ -886,6 +929,7 @@ export const advancedFields = [
]
export const customFields = [
/*
{
type: 'custom',
icon: 'custom-component',
@ -895,5 +939,22 @@ export const customFields = [
type: 'slot',
icon: 'slot-component',
},
*/
]
export function addContainerWidgetSchema(containerSchema) {
containers.push(containerSchema)
}
export function addBasicFieldSchema(fieldSchema) {
basicFields.push(fieldSchema)
}
export function addAdvancedFieldSchema(fieldSchema) {
advancedFields.push(fieldSchema)
}
export function addCustomWidgetSchema(widgetSchema) {
customFields.push(widgetSchema)
}

View File

@ -1,5 +1,6 @@
<template>
<el-col class="grid-cell" :span="widget.options.span" :class="[customClass]"
:offset="widget.options.offset || 0" :push="widget.options.push || 0" :pull="widget.options.pull || 0"
:key="widget.id" v-show="!widget.options.hidden">
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
<template v-for="(subWidget, swIdx) in widget.widgetList">
@ -24,15 +25,13 @@
<script>
import i18n from "../../../utils/i18n"
import refMixin from "../../../components/form-render/refMixin"
import ContainerItems from './index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
name: "GridColItem",
componentName: 'GridColItem',
componentName: 'ContainerItem',
mixins: [i18n, refMixin],
components: {
...ContainerItems,
...FieldComponents,
},
props: {

View File

@ -1,5 +1,11 @@
import Vue from "vue"
const requireComponent = require.context('./', false, /\w+\.vue$/)
/**
* 容器组件时递归组件且内部可以嵌套其他容器局部注册会找不到组件必须注册为全局组件原因不明
* begin
*
let comps = {}
requireComponent.keys().map(fileName => {
@ -8,3 +14,11 @@ requireComponent.keys().map(fileName => {
})
export default comps;
end */
/* 全局注册!! */
requireComponent.keys().map(fileName => {
let comp = requireComponent(fileName).default;
Vue.component(comp.name, comp)
})

View File

@ -29,7 +29,6 @@
import refMixin from "../../../components/form-render/refMixin"
import ContainerItemWrapper from './container-item-wrapper'
import containerItemMixin from "./containerItemMixin";
import ContainerItems from './index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
@ -38,7 +37,6 @@
mixins: [emitter, i18n, refMixin, containerItemMixin],
components: {
ContainerItemWrapper,
...ContainerItems,
...FieldComponents,
},
props: {

View File

@ -18,15 +18,13 @@
<script>
import i18n from "../../../utils/i18n"
import refMixin from "../../../components/form-render/refMixin"
import ContainerItems from './index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
name: "TableCellItem",
componentName: "TableCellItem",
componentName: "ContainerItem",
mixins: [i18n, refMixin],
components: {
...ContainerItems,
...FieldComponents,
},
props: {

View File

@ -29,7 +29,7 @@
<script>
//import ElForm from 'element-ui/packages/form/src/form.vue' /* Element UI */
import emitter from 'element-ui/lib/mixins/emitter'
import ContainerComponents from './container-item/index'
import './container-item/index'
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
import {deepClone, insertCustomCssToHead, insertGlobalFunctionsToHtml} from "../../utils/util"
import i18n, { changeLocale } from "../../utils/i18n"
@ -41,7 +41,6 @@
components: {
//ElForm,
...ContainerComponents,
...FieldComponents,
},
props: {

View File

@ -0,0 +1,106 @@
<template>
<el-container id="commonTable">
<el-main>
<el-table :data="data" :height="height" :max-height="maxHeight" border stripe tooltip-effect="light"
@selection-change="handleSelectionChange" :size="tableSize" :style="{width: tableWidth}">
<el-table-column v-if="showCheckBox" type="selection" width="45"></el-table-column>
<template v-for="(item, index) in columns">
<el-table-column
v-if="item.show !== false"
:key="index"
:fixed="item.fixed"
:prop="item.prop"
:label="item.label"
:align="item.align ? item.align:'center'"
:width="item.width"
:show-overflow-tooltip="true"
:formatter="item.formatter ? item.formatter : formatterValue">
</el-table-column>
</template>
<slot name="table_operation"/>
</el-table>
</el-main>
<el-footer id="simpleTableFooter" v-if="showPager" style="height: 42px;padding-top: 6px; background: white">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
style="text-align: right;margin:0;"
:current-page="pagination.pageNo"
:page-size="pagination.limit"
:page-sizes="pagination.sizes"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</el-footer>
</el-container>
</template>
<script>
export default {
name: 'VTable',
props: {
tableWidth: [String, Number],
columns: Array,
data: Array,
showPager: {
type: Boolean,
default: true
},
showCheckBox: {
type: Boolean,
default: false
},
pagination: Object,
height: {
type: String,
default: "100%"
},
maxHeight: {
type: Number,
default: 2000
},
tableSize: {
type: String,
default: 'medium'
},
},
methods: {
handleSelectionChange(val) {
this.$emit('handleSelectionChange', val);
},
handleSizeChange(val) {
this.$emit('handleSizeChange', val);
},
handleCurrentChange(val) {
this.$emit('handleCurrentChange', val);
},
formatterValue(row, column, cellValue) {
return cellValue;
}
}
}
</script>
<style lang="scss" scoped>
.el-table {
// table
overflow: auto;
//
position: relative;
::v-deep .el-table__fixed-header-wrapper thead th > .cell {
white-space: nowrap !important; /* 禁止表头换行 */
}
::v-deep .el-table__header-wrapper thead th > .cell {
white-space: nowrap !important; /* 禁止表头换行 */
}
::v-deep .el-table__body-wrapper {
//height: 100% !important;
}
}
</style>

View File

@ -0,0 +1,23 @@
import {
addContainerWidgetSchema,
addBasicFieldSchema,
addAdvancedFieldSchema,
addCustomWidgetSchema
} from '@/components/form-designer/widget-panel/widgetsConfig'
import {
registerCommonProperty,
registerAdvancedProperty,
registerEventProperty
} from '@/components/form-designer/setting-panel/propertyRegister'
export default {
addContainerWidgetSchema,
addBasicFieldSchema,
addAdvancedFieldSchema,
addCustomWidgetSchema,
registerCommonProperty,
registerAdvancedProperty,
registerEventProperty,
}

View File

@ -0,0 +1,97 @@
import Vue from 'vue'
import {
addContainerWidgetSchema,
addCustomWidgetSchema
} from '@/components/form-designer/widget-panel/widgetsConfig'
import * as PERegister from '@/components/form-designer/setting-panel/propertyRegister'
import * as PEFactory from '@/components/form-designer/setting-panel/property-editor-factory'
import {cardSchema} from "@/extension/samples/extension-schema"
import CardWidget from '@/extension/samples/card/card-widget'
import CardItem from '@/extension/samples/card/card-item'
import {alertSchema} from "@/extension/samples/extension-schema"
import AlertWidget from '@/extension/samples/alert/alert-widget'
export const loadExtension = function () {
/**
* 加载容器组件步骤
* 1. 加载组件Json Schema;
* 2. 全局注册容器组件容器组件有两种状态设计期和运行期故需要注册两个组件
* 3. 全局注册属性编辑器组件基本属性高级属性事件属性
* 4. 加载完毕
*/
addContainerWidgetSchema(cardSchema) //加载组件Json Schema
/* -------------------------------------------------- */
Vue.component(CardWidget.name, CardWidget) //设计期的容器组件
Vue.component(CardItem.name, CardItem) //运行期的容器组件
/* -------------------------------------------------- */
PERegister.registerCPEditor('cardWidth', 'card-cardWidth-editor',
PEFactory.createInputTextEditor('cardWidth', 'extension.setting.cardWidth'))
let shadowOptions = [
{label: 'never', value: 'never'},
{label: 'hover', value: 'hover'},
{label: 'always', value: 'always'},
]
PERegister.registerCPEditor('shadow', 'card-shadow-editor',
PEFactory.createSelectEditor('shadow', 'extension.setting.cardShadow',
{optionItems: shadowOptions}))
/* -------------------------------------------------- */
/* 容器组件加载完毕 end */
/**
* 加载字段组件步骤
* 1. 加载组件Json Schema;
* 2. 全局注册字段组件字段组件设计期和运行期共用故需要仅需注册一个组件
* 3. 全局注册属性编辑器组件基本属性高级属性事件属性
* 4. 加载完毕
*/
addCustomWidgetSchema(alertSchema) //加载组件Json Schema
/* -------------------------------------------------- */
Vue.component(AlertWidget.name, AlertWidget) //注册组件
/* -------------------------------------------------- */
PERegister.registerCPEditor('title', 'alert-title-editor',
PEFactory.createInputTextEditor('title', 'extension.setting.alertTitle'))
let typeOptions = [
{label: 'success', value: 'success'},
{label: 'warning', value: 'warning'},
{label: 'info', value: 'info'},
{label: 'error', value: 'error'},
]
PERegister.registerCPEditor('type', 'alert-type-editor',
PEFactory.createSelectEditor('type', 'extension.setting.alertType',
{optionItems: typeOptions}))
PERegister.registerCPEditor('description', 'alert-description-editor',
PEFactory.createInputTextEditor('description', 'extension.setting.description'))
PERegister.registerCPEditor('closable', 'alert-closable-editor',
PEFactory.createBooleanEditor('closable', 'extension.setting.closable'))
PERegister.registerCPEditor('closeText', 'alert-closeText-editor',
PEFactory.createInputTextEditor('closeText', 'extension.setting.closeText'))
PERegister.registerCPEditor('center', 'alert-center-editor',
PEFactory.createBooleanEditor('center', 'extension.setting.center'))
PERegister.registerCPEditor('showIcon', 'alert-showIcon-editor',
PEFactory.createBooleanEditor('showIcon', 'extension.setting.showIcon'))
let effectOptions = [
{label: 'light', value: 'light'},
{label: 'dark', value: 'dark'},
]
PERegister.registerCPEditor('effect', 'alert-effect-editor',
PEFactory.createRadioButtonGroupEditor('effect', 'extension.setting.effect',
{optionItems: effectOptions}))
PERegister.registerEPEditor('onClose', 'alert-onClose-editor',
PEFactory.createEventHandlerEditor('onClose', []))
/* -------------------------------------------------- */
/* 字段组件加载完毕 end */
}

View File

@ -0,0 +1,72 @@
<template>
<static-content-wrapper :designer="designer" :field="field" :design-state="designState"
:parent-widget="parentWidget" :parent-list="parentList" :index-of-parent-list="indexOfParentList"
:sub-form-row-index="subFormRowIndex" :sub-form-col-index="subFormColIndex" :sub-form-row-id="subFormRowId">
<el-alert ref="fieldEditor" :title="field.options.title" :type="field.options.type"
:description="field.options.description" :closable="field.options.closable"
:center="field.options.center" :close-text="field.options.closeText"
:show-icon="field.options.showIcon" :effect="field.options.effect" @close="handelCloseCustomEvent"></el-alert>
</static-content-wrapper>
</template>
<script>
import StaticContentWrapper from '@/components/form-designer/form-widget/field-widget/static-content-wrapper'
import emitter from 'element-ui/lib/mixins/emitter'
import i18n from "@/utils/i18n"
import fieldMixin from "@/components/form-designer/form-widget/field-widget/fieldMixin"
export default {
name: "alert-widget",
componentName: 'FieldWidget', //FieldWidgetbroadcast
mixins: [emitter, fieldMixin, i18n],
props: {
field: Object,
parentWidget: Object,
parentList: Array,
indexOfParentList: Number,
designer: Object,
designState: {
type: Boolean,
default: false
},
subFormRowIndex: { /* 子表单组件行索引从0开始计数 */
type: Number,
default: -1
},
subFormColIndex: { /* 子表单组件列索引从0开始计数 */
type: Number,
default: -1
},
subFormRowId: { /* 子表单组件行Id唯一id且不可变 */
type: String,
default: ''
},
},
components: {
StaticContentWrapper,
},
created() {
this.registerToRefList()
this.initEventHandler()
},
beforeDestroy() {
this.unregisterFromRefList()
},
methods: {
handelCloseCustomEvent() {
if (!!this.field.options.onClose) {
let changeFn = new Function(this.field.options.onClose)
changeFn.call(this)
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,66 @@
<template>
<container-item-wrapper>
<el-card :key="widget.id" class="card-container" :class="[customClass]"
:shadow="widget.options.shadow" :style="{width: widget.options.cardWidth + '!important' || ''}"
:ref="widget.id" v-show="!widget.options.hidden">
<div slot="header"><span>{{widget.options.label}}</span></div>
<template v-if="!!widget.widgetList && (widget.widgetList.length > 0)">
<template v-for="(subWidget, swIdx) in widget.widgetList">
<template v-if="'container' === subWidget.category">
<component :is="subWidget.type + '-item'" :widget="subWidget" :key="swIdx" :parent-list="widget.widgetList"
:index-of-parent-list="swIdx" :parent-widget="widget"></component>
</template>
<template v-else>
<component :is="subWidget.type + '-widget'" :field="subWidget" :designer="null" :key="swIdx" :parent-list="widget.widgetList"
:index-of-parent-list="swIdx" :parent-widget="widget"></component>
</template>
</template>
</template>
</el-card>
</container-item-wrapper>
</template>
<script>
import emitter from 'element-ui/lib/mixins/emitter'
import i18n from "@/utils/i18n"
import refMixin from "@/components/form-render/refMixin"
import ContainerItemWrapper from '@/components/form-render/container-item/container-item-wrapper'
import containerItemMixin from "@/components/form-render/container-item/containerItemMixin"
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
name: "card-item",
componentName: 'ContainerItem',
mixins: [emitter, i18n, refMixin, containerItemMixin],
components: {
ContainerItemWrapper,
...FieldComponents,
},
props: {
widget: Object,
},
inject: ['refList', 'sfRefList', 'globalModel'],
computed: {
customClass() {
return this.widget.options.customClass || ''
},
},
created() {
this.initRefList()
},
beforeDestroy() {
this.unregisterFromRefList()
},
methods: {
},
}
</script>
<style lang="scss" scoped>
::v-deep .el-card__header {
padding: 10px 12px;
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<container-wrapper :designer="designer" :widget="widget" :parent-widget="parentWidget" :parent-list="parentList"
:index-of-parent-list="indexOfParentList">
<el-card :key="widget.id" class="card-container" @click.native.stop="selectWidget(widget)"
:shadow="widget.options.shadow" :style="{width: widget.options.cardWidth + '!important' || ''}"
:class="[selected ? 'selected' : '', customClass]">
<div slot="header"><span>{{widget.options.label}}</span></div>
<draggable :list="widget.widgetList" v-bind="{group:'dragGroup', ghostClass: 'ghost',animation: 200}"
handle=".drag-handler"
@add="(evt) => onContainerDragAdd(evt, widget.widgetList)"
@update="onContainerDragUpdate" :move="checkContainerMove">
<transition-group name="fade" tag="div" class="form-widget-list">
<template v-for="(subWidget, swIdx) in widget.widgetList">
<template v-if="'container' === subWidget.category">
<component :is="subWidget.type + '-widget'" :widget="subWidget" :designer="designer" :key="subWidget.id" :parent-list="widget.widgetList"
:index-of-parent-list="swIdx" :parent-widget="widget"></component>
</template>
<template v-else>
<component :is="subWidget.type + '-widget'" :field="subWidget" :designer="designer" :key="subWidget.id" :parent-list="widget.widgetList"
:index-of-parent-list="swIdx" :parent-widget="widget" :design-state="true"></component>
</template>
</template>
</transition-group>
</draggable>
</el-card>
</container-wrapper>
</template>
<script>
import i18n from "@/utils/i18n"
import containerMixin from "@/components/form-designer/form-widget/container-widget/containerMixin"
import Draggable from 'vuedraggable'
import ContainerWrapper from "@/components/form-designer/form-widget/container-widget/container-wrapper"
import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
export default {
name: "card-widget",
componentName: 'ContainerWidget',
mixins: [i18n, containerMixin],
components: {
Draggable,
ContainerWrapper,
...FieldComponents,
},
props: {
widget: Object,
parentWidget: Object,
parentList: Array,
indexOfParentList: Number,
designer: Object,
},
computed: {
selected() {
return this.widget.id === this.designer.selectedId
},
customClass() {
return this.widget.options.customClass || ''
},
},
methods: {
/**
* 检查接收哪些组件拖放如不接受某些组件拖放则根据组件类型判断后返回false
* @param evt
* @returns {boolean}
*/
checkContainerMove(evt) {
return true
}
}
}
</script>
<style lang="scss" scoped>
.card-container.selected {
outline: 2px solid $--color-primary !important;
}
::v-deep .el-card__header {
padding: 10px 12px;
}
</style>

View File

@ -0,0 +1,34 @@
export const cardSchema = {
type: 'card',
category: 'container',
icon: 'card',
widgetList: [],
options: {
name: '',
label: 'card',
hidden: false,
cardWidth: '100%',
shadow: 'never',
customClass: '',
}
}
export const alertSchema = {
type: 'alert',
icon: 'alert',
formItemFlag: false,
options: {
name: '',
title: 'Good things are coming...',
type: 'info',
description: '',
closable: true,
closeText: '',
center: true,
showIcon: false,
effect: 'light',
hidden: false,
onClose: '',
customClass: '',
}
}

1
src/icons/svg/alert.svg Normal file
View File

@ -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="1634810180296" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6431" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300"><defs><style type="text/css"></style></defs><path d="M512 85.162667a319.573333 319.573333 0 0 1 319.829333 309.333333l0.170667 10.666667v174.805333l58.88 134.656a53.290667 53.290667 0 0 1-48.853333 74.709333L640 789.418667a128 128 0 0 1-255.786667 7.509333L384 789.290667l-201.6 0.042666a53.333333 53.333333 0 0 1-48.938667-74.581333L192 580.010667V405.162667c0-177.28 143.018667-320 320-320zM576 789.333333l-128 0.128a64 64 0 0 0 127.701333 6.144l0.256-6.272zM512 149.162667c-141.653333 0-256 114.090667-256 256v188.16L198.656 725.333333h627.072L768 593.365333V405.717333l-0.170667-9.6A255.488 255.488 0 0 0 512 149.162667z m384 202.837333h85.333333a32 32 0 0 1 4.352 63.701333L981.333333 416h-85.333333a32 32 0 0 1-4.352-63.701333L896 352z m-853.333333 0h85.333333a32 32 0 0 1 4.352 63.701333L128 416H42.666667a32 32 0 0 1-4.352-63.701333L42.666667 352z m921.6-243.2a32 32 0 0 1-2.816 41.685333l-3.584 3.114667-85.333334 64a32 32 0 0 1-41.984-48.085333l3.584-3.114667 85.333334-64a32 32 0 0 1 44.8 6.4zM104.533333 102.4l85.333334 64a32 32 0 1 1-38.4 51.2l-85.333334-64a32 32 0 1 1 38.4-51.2z" p-id="6432"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
src/icons/svg/card.svg Normal file
View File

@ -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="1634802035575" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4165" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300"><defs><style type="text/css"></style></defs><path d="M858.656 864H165.344C109.472 864 64 818.56 64 762.688V261.312C64 205.44 109.472 160 165.344 160h693.312C914.528 160 960 205.44 960 261.312v501.376C960 818.56 914.528 864 858.656 864zM165.344 224C144.736 224 128 240.736 128 261.312v501.376C128 783.264 144.736 800 165.344 800h693.312C879.264 800 896 783.264 896 762.688V261.312C896 240.736 879.264 224 858.656 224H165.344zM800 416H224c-17.664 0-32-14.336-32-32s14.336-32 32-32h576c17.696 0 32 14.336 32 32s-14.304 32-32 32zM320 736h-96c-17.664 0-32-14.304-32-32s14.336-32 32-32h96c17.664 0 32 14.304 32 32s-14.336 32-32 32z" fill="#333333" p-id="4166"></path></svg>

After

Width:  |  Height:  |  Size: 991 B

View File

@ -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="1634631759986" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11934" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300"><defs><style type="text/css"></style></defs><path d="M915.692 39.385H108.308c-15.754 0-29.539 13.784-29.539 29.538v98.462c0 15.753 13.785 29.538 29.539 29.538h807.384c15.754 0 29.539-13.785 29.539-29.538V68.923c0-15.754-13.785-29.538-29.539-29.538zM285.538 275.692h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V305.23c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V305.23c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V305.23c0-15.754-13.785-29.539-29.539-29.539zM285.538 472.615h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539zM285.538 669.538h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539z m315.077 0h-177.23c-15.754 0-29.539 13.785-29.539 29.539v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538v-59.077c0-15.754-13.785-29.539-29.539-29.539zM285.538 866.462h-177.23c-15.754 0-29.539 13.784-29.539 29.538v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V896c0-15.754-13.785-29.538-29.539-29.538z m315.077 0h-177.23c-15.754 0-29.539 13.784-29.539 29.538v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V896c0-15.754-13.785-29.538-29.539-29.538z m315.077 0h-177.23c-15.754 0-29.539 13.784-29.539 29.538v59.077c0 15.754 13.785 29.538 29.539 29.538h177.23c15.754 0 29.539-13.784 29.539-29.538V896c0-15.754-13.785-29.538-29.539-29.538z" p-id="11935"></path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -29,6 +29,7 @@ export default {
'grid-col': 'GridCol',
'table-cell': 'TableCell',
'tab-pane': 'TabPane',
'data-table': 'DataTable',
input: 'Input',
textarea: 'Textarea',
@ -154,7 +155,7 @@ export default {
commonSetting: 'Common Setting',
advancedSetting: 'Advanced Setting',
eventSetting: 'Event Setting',
fieldName: 'Unique Name',
uniqueName: 'Unique Name',
label: 'Label',
displayType: 'Type',
defaultValue: 'Default Value',
@ -212,12 +213,15 @@ export default {
fileTypesHelp: 'Allows to add more file types',
headers: 'Request Headers',
cellWidth: 'width',
cellHeight: 'height',
cellWidth: 'Width',
cellHeight: 'Height',
gutter: 'Gutter(px)',
columnSetting: 'Cols Setting',
colsOfGrid: 'Cols Of Grid:',
colSpanTitle: 'Spans Of Col',
colOffsetTitle: 'Offset Of Col',
colPushTitle: 'Push Of Col',
colPullTitle: 'Pull Of Col',
addColumn: 'Add Column',
tabPaneSetting: 'Tab Panes',

View File

@ -1,5 +1,24 @@
export default {
extension: {
widgetLabel: {
card: 'Card',
alert: 'Alert',
},
setting: {
cardWidth: 'Width Of Card',
cardShadow: 'Shadow',
alertTitle: 'Title',
alertType: 'Type',
description: 'Description',
closable: 'Closable',
closeText: 'Text On Close Btn',
center: 'Center',
showIcon: 'Show Icon',
effect: 'Effect',
},
}
}

View File

@ -29,6 +29,7 @@ export default {
'grid-col': '栅格列',
'table-cell': '单元格',
'tab-pane': '选项卡页',
'data-table': '数据表格',
input: '单行输入',
textarea: '多行输入',
@ -154,7 +155,7 @@ export default {
commonSetting: '常见属性',
advancedSetting: '高级属性',
eventSetting: '事件属性',
fieldName: '字段唯一名称',
uniqueName: '唯一名称',
label: '字段标签',
displayType: '显示类型',
defaultValue: '默认值',
@ -217,7 +218,10 @@ export default {
gutter: '栅格间隔(像素)',
columnSetting: '栅格属性设置',
colsOfGrid: '当前栅格列:',
colSpanTitle: '栅格列',
colSpanTitle: '栅格宽度',
colOffsetTitle: '左侧间隔格数',
colPushTitle: '右移栅格数',
colPullTitle: '左移栅格数',
addColumn: '增加栅格',
tabPaneSetting: '选项卡设置',

View File

@ -1,5 +1,24 @@
export default {
extension: {
widgetLabel: {
card: '卡片',
alert: '提示',
},
setting: {
cardWidth: '卡片宽度',
cardShadow: '显示阴影',
alertTitle: '标题',
alertType: '类型',
description: '辅助性文字',
closable: '是否可关闭',
closeText: '关闭按钮文字',
center: '文字居中',
showIcon: '显示图标',
effect: '显示效果',
},
}
}

View File

@ -11,6 +11,9 @@ import 'element-ui/lib/theme-chalk/index.css'
import '@/styles/index.scss'
import '@/iconfont/iconfont.css'
import {loadExtension} from '@/extension/extension-loader'
loadExtension()
Vue.use(ElementUI, { size: 'small' })

View File

@ -36,7 +36,6 @@ const langResources = {
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: localStorage.getItem('v_form_locale') || 'zh-CN',
//locale: 'en-US',
@ -58,6 +57,14 @@ export default {
methods: {
i18nt(key) {
return i18n._t(key, i18n.locale, i18n._getMessages())
}
},
/* 如果key1不存在则查找key2 */
i18n2t(key1, key2) {
return i18n.te(key1) ? i18n._t(key1, i18n.locale, i18n._getMessages()) :
i18n._t(key2, i18n.locale, i18n._getMessages())
},
}
}