提交 a1617cc1 authored 作者: 刘旭's avatar 刘旭

集成的表单设计的js改为setup语法糖,保持代码一致

上级 4881991c
......@@ -4,7 +4,7 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"serve": "vite preview --open",
"tsc": "vue-tsc --noEmit"
},
"dependencies": {
......
......@@ -15,6 +15,7 @@ export default {
</script>
<template>
<!-- el-config-provider 设置系统语言 -->
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
......@@ -28,6 +29,7 @@ export default {
/* 1px边框适配 */
.border-top-1px {
position: relative;
&::after {
content: "";
position: absolute;
......@@ -38,8 +40,10 @@ export default {
transform: scaleY(0.5);
}
}
.border-bottom-1px {
position: relative;
&::after {
content: "";
position: absolute;
......@@ -50,8 +54,10 @@ export default {
transform: scaleY(0.4);
}
}
.border-left-1px {
position: relative;
&::after {
content: "";
position: absolute;
......@@ -71,6 +77,7 @@ export default {
align-items: center;
justify-content: space-between;
}
/* 垂直居中对齐 */
.flex-center-h {
display: flex;
......@@ -90,16 +97,20 @@ export default {
flex-flow: wrap;
align-content: space-between;
}
/* flex布局end */
.font12 {
font-size: 12px;
}
.font14 {
font-size: 14px;
}
.font16 {
font-size: 16px;
}
/* 超出省略... */
.over1 {
overflow: hidden;
......@@ -141,5 +152,6 @@ export default {
-moz-line-clamp: 3 !important;
-moz-box-orient: vertical;
}
/* 超出省略...end */
</style>
......@@ -22,8 +22,6 @@ import { permission } from './directives/permission'
import SocketService from '@/socket/main'
// SocketService.Instance.connect();
import DesignForm from "../src/vueFormCreate";
// 国际化
import i18n from "@/lang/index";
......@@ -79,7 +77,6 @@ Object.keys(ElIconModules).forEach((key) => {
app.use(store, key)
app.use(router);
app.use(ElementPlus)
app.use(DesignForm);
app.use(i18n);
app.mount('#app');
//注册
......
......@@ -31,7 +31,7 @@
</div>
<!-- 详情页面 -->
<el-drawer v-model="visible" :title="title" size="80%" @close="handleClose">
<ElDesignForm ref="jsonRef" />
<ElDesignForm ref="designFormRef" />
<template #footer>
<span>
<el-button @click="handleClose">关闭</el-button>
......@@ -64,6 +64,7 @@
<script setup lang="ts">
import { ref, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from "element-plus";
import { ElDesignForm, ElGenerateForm } from "../../vueFormCreate";
import { getStructureList, saveStructure, getStructureData, deleteStructure, deleteStructureData } from '@/services/api/systemApi/formConfiguration/formConfiguration'
const visible = ref(false)
......@@ -72,7 +73,7 @@ const loading = ref(true)
const loadingDialog = ref(true)
const searchValue = ref('')
const tableList = ref()
const jsonRef = ref()
const designFormRef = ref()
const title = ref('详情')
const structureId = ref()
const dataList = ref()
......@@ -117,22 +118,23 @@ const handleScreen = () => init(searchValue.value, tablePage.value.pageNo, table
const handleAdd = () => {
title.value = '添加'
visible.value = true
nextTick(() => jsonRef.value.clear())
nextTick(() => designFormRef.value.clear())
}
const handleDetails = (row: any) => {
title.value = '详情'
visible.value = true
nextTick(() => jsonRef.value.detailJson(row.formJson))
nextTick(() => designFormRef.value.detailJson(row.formJson))
}
const handleEdit = (row: any) => {
title.value = '编辑'
structureId.value = row.id
visible.value = true
nextTick(() => jsonRef.value.detailJson(row.formJson))
nextTick(() => designFormRef.value.detailJson(row.formJson))
}
const handleQuery = (row: any) => {
formId.value = row.formId
dbTableName.value = row.dbTableName
......@@ -171,11 +173,11 @@ const deleteData = (id: any) => {
}
const onConfirm = () => {
const json = jsonRef.value.state.widgetForm
const json = designFormRef.value.state.widgetForm
if (title.value === '添加') {
saveStructure(json).then((res: any) => {
if (res.code === 200) {
jsonRef.value.handleClearable()
designFormRef.value.handleClearable()
init(searchValue.value, tablePage.value.pageNo, tablePage.value.pageSize)
visible.value = false
ElMessage({ type: 'success', message: '添加成功' })
......@@ -184,7 +186,7 @@ const onConfirm = () => {
} else {
saveStructure(json, structureId.value).then((res: any) => {
if (res.code === 200) {
jsonRef.value.handleClearable()
designFormRef.value.handleClearable()
init(searchValue.value, tablePage.value.pageNo, tablePage.value.pageSize)
visible.value = false
ElMessage({ type: 'success', message: '编辑成功' })
......@@ -195,7 +197,7 @@ const onConfirm = () => {
}
const handleClose = () => {
jsonRef.value.handleClearable()
designFormRef.value.handleClearable()
visible.value = false
}
......
......@@ -2,8 +2,8 @@
<div ref="aceRef" style="width: 100%; height: 350px;"></div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue'
<script lang="ts" setup>
import { onMounted, watch, ref } from 'vue'
// Ace 是一个用 JavaScript 编写的代码编辑器 仅生成文件
import ace, { Ace } from 'ace-builds'
......@@ -11,68 +11,58 @@ interface State {
aceRef?: HTMLElement
codeEditor?: Ace.Editor
}
const aceRef: any = ref<State>()
const codeEditor: any = ref<State>()
export default defineComponent({
name: 'CodeEditor',
props: {
value: {
type: String,
default: ''
},
language: {
type: String,
default: 'javascript'
},
theme: {
tyle: String,
default: 'github'
},
readonly: {
type: Boolean,
default: false
}
const props = defineProps({
value: {
type: String,
default: ''
},
language: {
type: String,
default: 'javascript'
},
theme: {
tyle: String,
default: 'github'
},
emits: ['update:value'],
setup(props, context) {
const state = reactive<State>({
aceRef: undefined,
codeEditor: undefined
})
readonly: {
type: Boolean,
default: false
}
})
onMounted(() => {
state.codeEditor = ace.edit(state.aceRef!, {
mode: `ace/mode/${props.language}`,
theme: `ace/theme/${props.theme}`,
value: props.value,
readOnly: props.readonly,
fontSize: 12,
tabSize: 2
})
const emits = defineEmits(['update:value'])
state.codeEditor.on('change', () =>
context.emit('update:value', state.codeEditor?.getValue())
)
})
onMounted(() => {
codeEditor.value = ace.edit(aceRef.value!, {
mode: `ace/mode/${props.language}`,
theme: `ace/theme/${props.theme}`,
value: props.value,
readOnly: props.readonly,
fontSize: 12,
tabSize: 2
})
watch(
() => props.value,
val => {
if (state.codeEditor) {
const currentPosition = state.codeEditor?.selection.getCursor()
state.codeEditor.setValue(val)
state.codeEditor.clearSelection()
state.codeEditor.gotoLine(
currentPosition.row + 1,
currentPosition.column,
true
)
}
}
)
codeEditor.value.on('change', () =>
emits('update:value', codeEditor.value?.getValue())
)
})
return {
...toRefs(state)
watch(
() => props.value,
val => {
if (codeEditor.value) {
const currentPosition = codeEditor.value?.selection.getCursor()
codeEditor.value.setValue(val)
codeEditor.value.clearSelection()
codeEditor.value.gotoLine(
currentPosition.row + 1,
currentPosition.column,
true
)
}
}
})
)
</script>
<template>
<div class="widget-cate">{{ title }}</div>
<Draggable
tag="ul"
item-key="type"
ghostClass="ghost"
:group="{ name: 'people', pull: 'clone', put: false }"
:sort="false"
:list="list"
>
<Draggable tag="ul" item-key="type" ghostClass="ghost" :group="{ name: 'people', pull: 'clone', put: false }"
:sort="false" :list="list">
<template #item="{ element }">
<li
class="form-edit-widget-label"
:class="{ 'no-put': element.tpye === 'divider' }"
>
<li class="form-edit-widget-label" :class="{ 'no-put': element.tpye === 'divider' }">
<a>
<SvgIcon :iconClass="element.type" />
<span>{{ element.label }}</span>
......@@ -22,25 +13,17 @@
</Draggable>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
<script lang="ts" setup>
import Draggable from 'vuedraggable'
import SvgIcon from './SvgIcon.vue'
export default defineComponent({
name: 'ComponentGroup',
components: {
Draggable,
SvgIcon
const props = defineProps({
title: {
type: String,
required: true
},
props: {
title: {
type: String,
required: true
},
list: {
required: true
}
list: {
required: true
}
})
</script>
......@@ -2,10 +2,9 @@
<div ref="editor"></div>
</template>
<script lang="ts">
<script lang="ts" setup>
import {
computed,
defineComponent,
onBeforeUnmount,
onMounted,
ref,
......@@ -13,50 +12,44 @@ import {
} from 'vue'
import WangEditor from 'wangeditor'
export default defineComponent({
name: 'RichTextEditor',
props: {
value: {
type: String,
default: ''
},
disable: {
type: Boolean,
default: false
}
const props = defineProps({
value: {
type: String,
default: ''
},
emits: ['update:value'],
setup(props, context) {
const editor = ref()
const content = computed({
set: val => context.emit('update:value', val),
get: () => props.value
})
let instance: WangEditor | null
onMounted(() => {
instance = new WangEditor(editor.value)
Object.assign(instance.config, {
zIndex: 9,
onchange: (html: string) => (content.value = html)
})
instance.create()
watchEffect(() =>
instance && props.disable ? instance.disable() : instance?.enable()
)
})
onBeforeUnmount(() => {
instance && instance.destroy()
instance = null
})
return {
editor
}
disable: {
type: Boolean,
default: false
}
})
const emits = defineEmits(['update:value'])
const editor = ref()
const content = computed({
set: val => emits('update:value', val),
get: () => props.value
})
let instance: WangEditor | null
onMounted(() => {
instance = new WangEditor(editor.value)
Object.assign(instance.config, {
zIndex: 9,
onchange: (html: string) => (content.value = html)
})
instance.create()
watchEffect(() =>
instance && props.disable ? instance.disable() : instance?.enable()
)
})
onBeforeUnmount(() => {
instance && instance.destroy()
instance = null
})
</script>
......@@ -5,45 +5,35 @@
</svg>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
<script lang="ts" setup>
import { computed } from 'vue'
import * as utils from '../utils'
export default defineComponent({
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
const props = defineProps({
iconClass: {
type: String,
required: true
},
setup(props) {
const isExternal = computed(() => utils.isExternal(props.iconClass))
const iconName = computed(() => `#icon-${props.iconClass}`)
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`
} else {
return 'svg-icon'
}
})
const styleExternalIcon = computed(() => ({
mask: `url(${props.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${props.iconClass}) no-repeat 50% 50%`
}))
className: {
type: String,
default: ''
}
})
return {
isExternal,
iconName,
svgClass,
styleExternalIcon
}
const isExternal = computed(() => utils.isExternal(props.iconClass))
const iconName = computed(() => `#icon-${props.iconClass}`)
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`
} else {
return 'svg-icon'
}
})
const styleExternalIcon = computed(() => ({
mask: `url(${props.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${props.iconClass}) no-repeat 50% 50%`
}))
</script>
<style lang="scss" scoped>
......
......@@ -16,9 +16,9 @@ export interface WidgetForm {
size: any
hideRequiredAsterisk: boolean
labelWidth: number
labelPosition: string
labelPosition: any
dbTableName: string
dbTableComment: string,
dbTableComment: string
formId: string
}
}
......@@ -49,7 +49,7 @@ export const widgetForm: WidgetForm = {
}
export const put = () => {
console.log('widgetForm', widgetForm);
}
export const basicComponents = [
......
......@@ -34,15 +34,14 @@
</el-header>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script lang="ts" setup>
import SvgIcon from '../../components/SvgIcon.vue'
export default defineComponent({
name: 'CustomHeader',
components: {
SvgIcon
},
emits: ['uploadJson', 'clearable', 'preview', 'generateJson', 'generateCode']
})
const emits = defineEmits(['uploadJson', 'clearable', 'preview', 'generateJson', 'generateCode'])
</script>
<style lang="scss" scoped>
:deep(.el-icon) {
width: 2em;
}
</style>
......@@ -11,92 +11,95 @@
</div>
</el-aside>
<el-main class="center-container">
<ElCustomHeader v-bind="$props" @preview="() => (previewVisible = true)"
@uploadJson="() => (uploadJsonVisible = true)" @generateJson="handleGenerateJson"
<ElCustomHeader v-bind="$props" @preview="() => (state.previewVisible = true)"
@uploadJson="() => (state.uploadJsonVisible = true)" @generateJson="handleGenerateJson"
@generateCode="handleGenerateCode" @clearable="handleClearable">
<slot name="header"></slot>
</ElCustomHeader>
<el-main :class="{ 'widget-empty': widgetForm.list }">
<ElWidgetForm ref="widgetFormRef" v-model:widgetForm="widgetForm"
v-model:widgetFormSelect="widgetFormSelect" />
<el-main :class="{ 'widget-empty': state.widgetForm.list }">
<ElWidgetForm ref="widgetFormRef" v-model:widgetForm="state.widgetForm"
v-model:widgetFormSelect="state.widgetFormSelect" />
</el-main>
</el-main>
<el-aside class="widget-config-container" width="300px">
<el-container>
<el-header>
<div class="config-tab" :class="{ active: configTab === 'widget' }" @click="configTab = 'widget'">
<div class="config-tab" :class="{ active: state.configTab === 'widget' }"
@click="state.configTab = 'widget'">
字段属性
</div>
<div class="config-tab" :class="{ active: configTab === 'form' }" @click="configTab = 'form'">
<div class="config-tab" :class="{ active: state.configTab === 'form' }"
@click="state.configTab = 'form'">
表单属性
</div>
</el-header>
<el-main class="config-content">
<ElWidgetConfig v-show="configTab === 'widget'" v-model:select="widgetFormSelect" />
<ElFormConfig v-show="configTab === 'form'" v-model:config="widgetForm.config" ref="formConfigRef" />
<ElWidgetConfig v-show="state.configTab === 'widget'" v-model:select="state.widgetFormSelect" />
<ElFormConfig v-show="state.configTab === 'form'" v-model:config="state.widgetForm.config"
ref="formConfigRef" />
</el-main>
</el-container>
</el-aside>
</el-container>
</el-main>
<el-dialog v-model="uploadJsonVisible" title="导入JSON" :width="800">
<el-dialog v-model="state.uploadJsonVisible" title="导入JSON" :width="800">
<el-alert type="info" title="JSON格式如下,直接复制生成的json覆盖此处代码点击确定即可" style="margin-bottom: 10px" />
<CodeEditor v-model:value="jsonEg" language="json" />
<CodeEditor v-model:value="state.jsonEg" language="json" />
<template #footer>
<el-button @click="() => (uploadJsonVisible = false)">取消</el-button>
<el-button @click="() => (state.uploadJsonVisible = false)">取消</el-button>
<el-button type="primary" @click="handleUploadJson">导入</el-button>
</template>
</el-dialog>
<el-dialog v-model="previewVisible" title="预览" :width="800">
<ElGenerateForm ref="generateFormRef" v-if="previewVisible" :data="widgetForm" />
<el-dialog v-model="state.previewVisible" title="预览" :width="800">
<ElGenerateForm ref="generateFormRef" v-if="state.previewVisible" :data="state.widgetForm" />
<template #footer>
<el-button @click="handleReset">重置</el-button>
<el-button type="primary" @click="handleGetData">获取数据</el-button>
</template>
<el-dialog v-model="dataJsonVisible" title="获取数据" :width="800">
<CodeEditor :value="dataJsonTemplate" language="json" readonly />
<el-dialog v-model="state.dataJsonVisible" title="获取数据" :width="800">
<CodeEditor :value="state.dataJsonTemplate" language="json" readonly />
<template #footer>
<el-button @click="() => (dataJsonVisible = false)">取消</el-button>
<el-button type="primary" @click="handleCopyClick(dataJsonTemplate)">Copy</el-button>
<el-button @click="() => (state.dataJsonVisible = false)">取消</el-button>
<el-button type="primary" @click="handleCopyClick(state.dataJsonTemplate)">Copy</el-button>
</template>
</el-dialog>
</el-dialog>
<el-dialog v-model="generateJsonVisible" title="生成JSON" :width="800">
<CodeEditor :value="generateJsonTemplate" language="json" readonly />
<el-dialog v-model="state.generateJsonVisible" title="生成JSON" :width="800">
<CodeEditor :value="state.generateJsonTemplate" language="json" readonly />
<template #footer>
<el-button @click="() => (generateJsonVisible = false)">取消</el-button>
<el-button type="primary" @click="onConfirm(generateJsonTemplate)">确认</el-button>
<el-button type="primary" @click="handleCopyClick(generateJsonTemplate)">Copy</el-button>
<el-button @click="() => (state.generateJsonVisible = false)">取消</el-button>
<el-button type="primary" @click="onConfirm(state.generateJsonTemplate)">确认</el-button>
<el-button type="primary" @click="handleCopyClick(state.generateJsonTemplate)">Copy</el-button>
</template>
</el-dialog>
<el-dialog v-model="dataCodeVisible" title="生产代码" :width="800">
<el-tabs type="card" v-model="codeLanguage" :tabBarStyle="{ margin: 0 }">
<el-tab-pane label="Vue Component" :name="codeType.Vue">
<CodeEditor :value="dataCodeTemplate" language="html" readonly />
<el-dialog v-model="state.dataCodeVisible" title="生产代码" :width="800">
<el-tabs type="card" v-model="state.codeLanguage" :tabBarStyle="{ margin: 0 }">
<el-tab-pane label="Vue Component" :name="state.codeType.Vue">
<CodeEditor :value="state.dataCodeTemplate" language="html" readonly />
</el-tab-pane>
<el-tab-pane label="HTML" :name="codeType.Html">
<CodeEditor :value="dataCodeTemplate" language="html" readonly />
<el-tab-pane label="HTML" :name="state.codeType.Html">
<CodeEditor :value="state.dataCodeTemplate" language="html" readonly />
</el-tab-pane>
</el-tabs>
<template #footer>
<el-button @click="() => (dataCodeVisible = false)">取消</el-button>
<el-button type="primary" @click="handleCopyClick(dataCodeTemplate)">Copy</el-button>
<el-button @click="() => (state.dataCodeVisible = false)">取消</el-button>
<el-button type="primary" @click="handleCopyClick(state.dataCodeTemplate)">Copy</el-button>
</template>
</el-dialog>
</el-container>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, PropType, toRefs, watchEffect, ref, nextTick } from 'vue'
<script lang="ts" setup>
import { reactive, PropType, toRefs, watchEffect, ref, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { defaultsDeep } from 'lodash'
import CodeEditor from '../../components/CodeEditor.vue'
......@@ -110,200 +113,172 @@ import { element } from '../../config'
import { copy } from '../../utils'
import { CodeType, PlatformType } from '../../enums'
import generateCode from '../../utils/generateCode'
import { WidgetForm, widgetForm } from '../../config/element'
// import { getGenerate, saveGenerate } from '@/services/api/table/tableCreator/tableCreatorAPI'
import { WidgetForm } from '../../config/element'
export default defineComponent({
name: 'ElDesignForm',
components: {
ElCustomHeader,
ComponentGroup,
CodeEditor,
ElWidgetForm,
ElGenerateForm,
ElWidgetConfig,
ElFormConfig
const props = defineProps({
preview: {
type: Boolean,
default: true
},
props: {
preview: {
type: Boolean,
default: true
},
generateCode: {
type: Boolean,
default: true
},
generateJson: {
type: Boolean,
default: true
},
uploadJson: {
type: Boolean,
default: true
},
clearable: {
type: Boolean,
default: true
}
generateCode: {
type: Boolean,
default: true
},
setup(props: any, context: any) {
const state = reactive({
element,
codeType: CodeType,
widgetForm: JSON.parse(JSON.stringify(element.widgetForm)),
widgetFormSelect: undefined,
generateFormRef: null as any,
configTab: 'widget',
previewVisible: false,
uploadJsonVisible: false,
dataJsonVisible: false,
dataCodeVisible: false,
generateJsonVisible: false,
generateCodeVisible: false,
generateJsonTemplate: JSON.stringify(element.widgetForm, null, 2),
generateJsonTemplate1: element.widgetForm,
dataJsonTemplate: '',
dataCodeTemplate: '',
codeLanguage: CodeType.Vue,
jsonEg: JSON.stringify(element.widgetForm, null, 2),
loading: false
})
const formConfigRef = ref()
generateJson: {
type: Boolean,
default: true
},
uploadJson: {
type: Boolean,
default: true
},
clearable: {
type: Boolean,
default: true
}
})
const showPreviewVisible = () => {
state.previewVisible = true
}
const state = reactive({
element,
codeType: CodeType,
widgetForm: JSON.parse(JSON.stringify(element.widgetForm)),
widgetFormSelect: undefined,
generateFormRef: null as any,
configTab: 'widget',
previewVisible: false,
uploadJsonVisible: false,
dataJsonVisible: false,
dataCodeVisible: false,
generateJsonVisible: false,
generateCodeVisible: false,
generateJsonTemplate: JSON.stringify(element.widgetForm, null, 2),
generateJsonTemplate1: element.widgetForm,
dataJsonTemplate: '',
dataCodeTemplate: '',
codeLanguage: CodeType.Vue,
jsonEg: JSON.stringify(element.widgetForm, null, 2),
loading: false
})
const showGenerateJsonVisible = () => {
state.generateJsonVisible = true
}
const detailJson = (Json: string) => {
if (Json) {
state.widgetForm = {}
nextTick(() => defaultsDeep(state.widgetForm, JSON.parse(Json))) // 加载速度要比下面快
formConfigRef.value.updataNewData(JSON.parse(Json))
}
}
// 导入json
const handleUploadJson = () => {
try {
state.widgetForm.list = []
defaultsDeep(state.widgetForm, JSON.parse(state.jsonEg))
const formConfigRef = ref()
if (state.widgetForm.list) state.widgetFormSelect = state.widgetForm.list[0]
const showPreviewVisible = () => {
state.previewVisible = true
}
state.uploadJsonVisible = false
ElMessage.success('上传成功')
} catch (error) {
ElMessage.error('上传失败')
}
}
// 确认
const onConfirm = (text: string) => {
state.generateJsonVisible = false
}
const handleCopyClick = (text: string) => {
copy(text)
ElMessage.success('Copy成功')
}
// 获取数据
const handleGetData = () => {
state.generateFormRef.getData().then((res: any) => {
const dataForm = {
id: '',
list: res,
formid: state.widgetForm.config.formField
}
console.log('Object数据', dataForm);
state.dataJsonTemplate = JSON.stringify(dataForm, null, 2)
console.log('json数据', state.dataJsonTemplate);
state.dataJsonVisible = true
})
}
const showGenerateJsonVisible = () => {
state.generateJsonVisible = true
}
const detailJson = (Json: string) => {
if (Json) {
state.widgetForm = {}
nextTick(() => defaultsDeep(state.widgetForm, JSON.parse(Json))) // 加载速度要比下面快
formConfigRef.value.updataNewData(JSON.parse(Json))
}
}
// 导入json
const handleUploadJson = () => {
try {
state.widgetForm.list = []
defaultsDeep(state.widgetForm, JSON.parse(state.jsonEg))
// 生成json代码
const handleGenerateJson = () => {
(state.generateJsonTemplate = JSON.stringify(
state.widgetForm,
null,
2
)) && (state.generateJsonVisible = true)
}
if (state.widgetForm.list) state.widgetFormSelect = state.widgetForm.list[0]
// 生成json代码
const handleGenerateJson1 = () => {
(state.generateJsonTemplate = JSON.stringify(
state.widgetForm,
null,
2
))
state.uploadJsonVisible = false
ElMessage.success('上传成功')
} catch (error) {
ElMessage.error('上传失败')
}
}
// 确认
const onConfirm = (text: string) => {
state.generateJsonVisible = false
}
const handleCopyClick = (text: string) => {
copy(text)
ElMessage.success('Copy成功')
}
// 获取数据
const handleGetData = () => {
state.generateFormRef.getData().then((res: any) => {
const dataForm = {
id: '',
list: res,
formid: state.widgetForm.config.formField
}
console.log('Object数据', dataForm);
state.dataJsonTemplate = JSON.stringify(dataForm, null, 2)
console.log('json数据', state.dataJsonTemplate);
state.dataJsonVisible = true
})
}
const handleGenerateCode = () => {
state.codeLanguage = CodeType.Vue
state.dataCodeVisible = true
}
// 生成json代码
const handleGenerateJson = () => {
(state.generateJsonTemplate = JSON.stringify(
state.widgetForm,
null,
2
)) && (state.generateJsonVisible = true)
}
watchEffect(() => {
if (state.dataCodeVisible) {
state.dataCodeTemplate = generateCode(
state.widgetForm,
state.codeLanguage,
PlatformType.Element
)!
}
})
// 生成json代码
const handleGenerateJson1 = () => {
(state.generateJsonTemplate = JSON.stringify(
state.widgetForm,
null,
2
))
}
const handleClearable = () => {
state.widgetForm.list = []
nextTick(() => defaultsDeep(
state.widgetForm,
JSON.parse(JSON.stringify(element.widgetForm))
))
state.widgetFormSelect = undefined
}
const handleGenerateCode = () => {
state.codeLanguage = CodeType.Vue
state.dataCodeVisible = true
}
const handleReset = () => state.generateFormRef.reset()
watchEffect(() => {
if (state.dataCodeVisible) {
state.dataCodeTemplate = generateCode(
state.widgetForm,
state.codeLanguage,
PlatformType.Element
)!
}
})
const getJson = () => state.widgetForm
const handleClearable = () => {
state.widgetForm.list = []
nextTick(() => defaultsDeep(
state.widgetForm,
JSON.parse(JSON.stringify(element.widgetForm))
))
state.widgetFormSelect = undefined
}
const setJson = (json: WidgetForm) => {
state.widgetForm.list = []
defaultsDeep(state.widgetForm, json)
if (json.list.length) {
state.widgetFormSelect = json.list[0]
}
}
const handleReset = () => state.generateFormRef.reset()
const getTemplate = (codeType: CodeType) =>
generateCode(state.widgetForm, codeType, PlatformType.Element)
const getJson = () => state.widgetForm
const clear = () => {
handleClearable()
formConfigRef.value.updataNewData(element.widgetForm)
}
return {
state,
formConfigRef,
...toRefs(state),
handleUploadJson,
handleCopyClick,
handleGetData,
handleGenerateJson,
handleGenerateJson1,
handleGenerateCode,
handleClearable,
handleReset,
getJson,
setJson,
getTemplate,
showPreviewVisible,
showGenerateJsonVisible,
onConfirm,
detailJson,
clear
}
const setJson = (json: WidgetForm) => {
state.widgetForm.list = []
defaultsDeep(state.widgetForm, json)
if (json.list.length) {
state.widgetFormSelect = json.list[0]
}
}
const getTemplate = (codeType: CodeType) =>
generateCode(state.widgetForm, codeType, PlatformType.Element)
const clear = () => {
handleClearable()
formConfigRef.value.updataNewData(element.widgetForm)
}
defineExpose({
state,
handleClearable,
detailJson,
clear
})
</script>
......@@ -37,39 +37,31 @@
</div>
</template>
<script lang="ts">
<script lang="ts" setup>
import { WidgetForm } from '../../config/element'
import { element } from '../../config'
import { defineComponent, PropType, ref, watch } from 'vue'
import { PropType, ref, watch } from 'vue'
export default defineComponent({
name: 'ElFormConfig',
props: {
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
}
},
emits: ['update:config'],
setup(props, context) {
const data = ref(props.config)
watch(data, () => {
context.emit('update:config', data)
})
const state = ref<any>({
widgetForm: element.widgetForm
})
const props = defineProps({
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
}
})
const emits = defineEmits(['update:config'])
const data = ref(props.config)
// 编辑时更新数据
const updataNewData = (value: any) => data.value = value.config
watch(data, () => {
emits('update:config', data)
})
const state = ref<any>({
widgetForm: element.widgetForm
})
// 编辑时更新数据
const updataNewData = (value: any) => data.value = value.config
return {
data,
state,
updataNewData
}
}
defineExpose({
updataNewData
})
</script>
<template>
<div class="fc-style" style="padding: 20px;">
<el-form ref="generateForm" label-suffix=":" :model="model" :rules="rules" :size="widgetForm.config.size"
:label-position="widgetForm.config.labelPosition" :label-width="`${widgetForm.config.labelWidth}px`"
:hide-required-asterisk="widgetForm.config.hideRequiredAsterisk">
<template v-for="(element, index) of widgetForm.list">
<el-form ref="generateForm" label-suffix=":" :model="state.model" :rules="state.rules"
:size="state.widgetForm.config.size" :label-position="state.widgetForm.config.labelPosition"
:label-width="`${state.widgetForm.config.labelWidth}px`"
:hide-required-asterisk="state.widgetForm.config.hideRequiredAsterisk">
<template v-for="(element, index) of state.widgetForm.list">
<template v-if="element.type === 'grid'">
<el-row type="flex" v-if="element.key" :key="element.key" :gutter="element.options.gutter ?? 0"
:justify="element.options.justify" :align="element.options.align">
<el-col v-for="(col, colIndex) of element.columns" :key="colIndex" :span="col.span ?? 0">
<ElGenerateFormItem v-for="colItem of col.list" :model="model" :key="colItem.key" :element="colItem"
<ElGenerateFormItem v-for="colItem of col.list" :model="state.model" :key="colItem.key" :element="colItem"
:config="data.config" :disabled="disabled" />
</el-col>
</el-row>
</template>
<ElGenerateFormItem v-else :model="model" :key="element.key" :element="widgetForm.list[index]"
<ElGenerateFormItem v-else :model="state.model" :key="element.key" :element="state.widgetForm.list[index]"
:config="data.config" :disabled="disabled" />
</template>
</el-form>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue'
<script lang="ts" setup>
import { onMounted, reactive, toRefs, watch } from 'vue'
import { ElMessage } from 'element-plus'
import ElGenerateFormItem from './ElGenerateFormItem.vue'
import { element } from '../../config'
export default defineComponent({
name: 'ElGenerateForm',
components: {
ElGenerateFormItem
const props = defineProps({
data: {
type: Object,
default: element.widgetForm
},
props: {
data: {
type: Object,
default: element.widgetForm
},
value: {
type: Object
},
disabled: {
type: Boolean,
default: false
}
value: {
type: Object
},
setup(props) {
const state = reactive({
generateForm: null as any,
model: {} as any,
rules: {} as any,
widgetForm:
(props.data && JSON.parse(JSON.stringify(props.data))) ??
element.widgetForm
})
const generateModel = (list: any[]) => {
for (let index = 0; index < list.length; index++) {
const model = list[index].model
if (!model) {
return
}
if (list[index].type === 'grid') {
list[index].columns.forEach((col: any) => generateModel(col.list))
} else {
if (props.value && Object.keys(props.value).includes(model)) {
state.model[model] = props.value[model]
} else {
state.model[model] = list[index].options.defaultValue
}
disabled: {
type: Boolean,
default: false
}
})
state.rules[model] = list[index].options.rules
}
const state = reactive({
generateForm: null as any,
model: {} as any,
rules: {} as any,
widgetForm:
(props.data && JSON.parse(JSON.stringify(props.data))) ??
element.widgetForm
})
const generateModel = (list: any[]) => {
for (let index = 0; index < list.length; index++) {
const model = list[index].model
if (!model) {
return
}
if (list[index].type === 'grid') {
list[index].columns.forEach((col: any) => generateModel(col.list))
} else {
if (props.value && Object.keys(props.value).includes(model)) {
state.model[model] = props.value[model]
} else {
state.model[model] = list[index].options.defaultValue
}
state.rules[model] = list[index].options.rules
}
}
}
const generateOptions = (list: any[]) => {
list.forEach(item => {
if (item.type === 'grid') {
item.columns.forEach((col: any) => generateOptions(col.list))
} else {
if (item.options.remote && item.options.remoteFunc) {
fetch(item.options.remoteFunc)
.then(resp => resp.json())
.then(json => {
if (json instanceof Array) {
item.options.remoteOptions = json.map(data => ({
label: data[item.options.props.label],
value: data[item.options.props.value],
children: data[item.options.props.children]
}))
}
})
}
}
})
const generateOptions = (list: any[]) => {
list.forEach(item => {
if (item.type === 'grid') {
item.columns.forEach((col: any) => generateOptions(col.list))
} else {
if (item.options.remote && item.options.remoteFunc) {
fetch(item.options.remoteFunc)
.then(resp => resp.json())
.then(json => {
if (json instanceof Array) {
item.options.remoteOptions = json.map(data => ({
label: data[item.options.props.label],
value: data[item.options.props.value],
children: data[item.options.props.children]
}))
}
})
}
}
})
}
watch(
() => props.data,
val => {
state.widgetForm =
(val && JSON.parse(JSON.stringify(val))) ?? element.widgetForm
state.model = {}
state.rules = {}
generateModel(state.widgetForm.list)
generateOptions(state.widgetForm.list)
},
{ deep: true, immediate: true }
)
watch(
() => props.data,
val => {
state.widgetForm =
(val && JSON.parse(JSON.stringify(val))) ?? element.widgetForm
state.model = {}
state.rules = {}
generateModel(state.widgetForm.list)
generateOptions(state.widgetForm.list)
},
{ deep: true, immediate: true }
)
onMounted(() => {
generateModel(state.widgetForm?.list ?? [])
generateOptions(state.widgetForm?.list ?? [])
})
onMounted(() => {
generateModel(state.widgetForm?.list ?? [])
generateOptions(state.widgetForm?.list ?? [])
})
const getData = () => {
return new Promise((resolve, reject) => {
state.generateForm
.validate()
.then((validate: boolean) => {
if (validate) {
// console.log('成功', state.generateForm);
resolve(state.model)
} else {
// console.log('失败');
ElMessage.error('验证失败')
}
})
.catch((error: Error) => {
reject(error)
})
const getData = () => {
return new Promise((resolve, reject) => {
state.generateForm
.validate()
.then((validate: boolean) => {
if (validate) {
// console.log('成功', state.generateForm);
resolve(state.model)
} else {
// console.log('失败');
ElMessage.error('验证失败')
}
})
}
.catch((error: Error) => {
reject(error)
})
})
}
const reset = () => {
state.generateForm.resetFields()
}
const reset = () => {
state.generateForm.resetFields()
}
return {
...toRefs(state),
getData,
reset
}
}
defineExpose({
...toRefs(state),
getData,
reset
})
</script>
<template>
<el-form-item v-if="element" :key="element.key" :label="element.label" :prop="element.model">
<template v-if="element.type === 'input'">
<el-input
v-model="data"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable"
:readonly="element.options.readonly"
:disabled="disabled || element.options.disabled"
>
<el-input v-model="data" :style="{ width: element.options.width }" :placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)" :clearable="element.options.clearable"
:readonly="element.options.readonly" :disabled="disabled || element.options.disabled">
<template #prefix v-if="element.options.prefix">{{ element.options.prefix }}</template>
<template #suffix v-if="element.options.suffix">{{ element.options.suffix }}</template>
<template #prepend v-if="element.options.prepend">{{ element.options.prepend }}</template>
......@@ -18,16 +12,10 @@
</template>
<template v-if="element.type === 'password'">
<el-input
v-model="data"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable"
:disabled="disabled || element.options.disabled"
:readonly="element.options.readonly"
:show-password="element.options.showPassword"
>
<el-input v-model="data" :style="{ width: element.options.width }" :placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)" :clearable="element.options.clearable"
:disabled="disabled || element.options.disabled" :readonly="element.options.readonly"
:show-password="element.options.showPassword">
<template #prefix v-if="element.options.prefix">{{ element.options.prefix }}</template>
<template #suffix v-if="element.options.suffix">{{ element.options.suffix }}</template>
<template #prepend v-if="element.options.prepend">{{ element.options.prepend }}</template>
......@@ -36,149 +24,81 @@
</template>
<template v-if="element.type === 'textarea'">
<el-input
type="textarea"
resize="none"
v-model="data"
:rows="element.options.rows"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:show-word-limit="element.options.showWordLimit"
:autosize="element.options.autosize"
:clearable="element.options.clearable"
:readonly="element.options.readonly"
:disabled="disabled || element.options.disabled"
/>
<el-input type="textarea" resize="none" v-model="data" :rows="element.options.rows"
:style="{ width: element.options.width }" :placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)" :show-word-limit="element.options.showWordLimit"
:autosize="element.options.autosize" :clearable="element.options.clearable" :readonly="element.options.readonly"
:disabled="disabled || element.options.disabled" />
</template>
<template v-if="element.type === 'number'">
<el-input-number
v-model="data"
:style="{ width: element.options.width }"
:max="element.options.max"
:min="element.options.min"
:disabled="disabled || element.options.disabled"
/>
<el-input-number v-model="data" :style="{ width: element.options.width }" :max="element.options.max"
:min="element.options.min" :disabled="disabled || element.options.disabled" />
</template>
<template v-if="element.type === 'radio'">
<el-radio-group
v-model="data"
:style="{ width: element.options.width }"
:disabled="disabled || element.options.disabled"
>
<el-radio
v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options"
:key="item.value"
:label="item.value"
:style="{
display: element.options.inline ? 'inline-block' : 'block'
}"
>{{ element.options.showLabel ? item.label : item.value }}</el-radio>
<el-radio-group v-model="data" :style="{ width: element.options.width }"
:disabled="disabled || element.options.disabled">
<el-radio v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options" :key="item.value" :label="item.value" :style="{
display: element.options.inline ? 'inline-block' : 'block'
}">{{ element.options.showLabel ? item.label : item.value }}</el-radio>
</el-radio-group>
</template>
<template v-if="element.type === 'checkbox' && data">
<el-checkbox-group
v-model="data"
:style="{ width: element.options.width }"
:disabled="disabled || element.options.disabled"
>
<el-checkbox
v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options"
:key="item.value"
:value="item.value"
:style="{
display: element.options.inline ? 'inline-block' : 'block'
}"
>
<el-checkbox-group v-model="data" :style="{ width: element.options.width }"
:disabled="disabled || element.options.disabled">
<el-checkbox v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options" :key="item.value" :value="item.value" :style="{
display: element.options.inline ? 'inline-block' : 'block'
}">
{{
element.options.showLabel ? item.label : item.value
element.options.showLabel ? item.label : item.value
}}
</el-checkbox>
</el-checkbox-group>
</template>
<template v-if="element.type === 'time'">
<el-time-picker
v-model="data"
:placeholder="element.options.placeholder"
:readonly="element.options.readonly"
:editable="element.options.editable"
:clearable="element.options.clearable"
:format="element.options.format"
:disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-time-picker v-model="data" :placeholder="element.options.placeholder" :readonly="element.options.readonly"
:editable="element.options.editable" :clearable="element.options.clearable" :format="element.options.format"
:disabled="disabled || element.options.disabled" :style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'date'">
<el-date-picker
v-model="data"
:placeholder="element.options.placeholder"
:readonly="element.options.readonly"
:editable="element.options.editable"
:clearable="element.options.clearable"
:format="element.options.format"
:disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-date-picker v-model="data" :placeholder="element.options.placeholder" :readonly="element.options.readonly"
:editable="element.options.editable" :clearable="element.options.clearable" :format="element.options.format"
:disabled="disabled || element.options.disabled" :style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'rate'">
<el-rate
v-model="data"
:max="element.options.max"
:allowHalf="element.options.allowHalf"
:disabled="disabled || element.options.disabled"
/>
<el-rate v-model="data" :max="element.options.max" :allowHalf="element.options.allowHalf"
:disabled="disabled || element.options.disabled" />
</template>
<template v-if="element.type === 'select'">
<el-select
v-model="data"
:multiple="element.options.multiple"
:placeholder="element.options.placeholder"
:clearable="element.options.clearable"
:filterable="element.options.filterable"
:disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }"
>
<el-option
v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options"
:key="item.value"
:value="item.value"
:label="element.options.showLabel ? item.label : item.value"
/>
<el-select v-model="data" :multiple="element.options.multiple" :placeholder="element.options.placeholder"
:clearable="element.options.clearable" :filterable="element.options.filterable"
:disabled="disabled || element.options.disabled" :style="{ width: element.options.width }">
<el-option v-for="item of element.options.remote
? element.options.remoteOptions
: element.options.options" :key="item.value" :value="item.value"
:label="element.options.showLabel ? item.label : item.value" />
</el-select>
</template>
<template v-if="element.type === 'switch'">
<el-switch
v-model="data"
:active-text="element.options.activeText"
:inactive-text="element.options.inactiveText"
:disabled="disabled || element.options.disabled"
/>
<el-switch v-model="data" :active-text="element.options.activeText" :inactive-text="element.options.inactiveText"
:disabled="disabled || element.options.disabled" />
</template>
<template v-if="element.type === 'slider'">
<el-slider
v-model="data"
:min="element.options.min"
:max="element.options.max"
:step="element.options.step"
:range="element.options.range"
:disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-slider v-model="data" :min="element.options.min" :max="element.options.max" :step="element.options.step"
:range="element.options.range" :disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type == 'text'">
......@@ -186,17 +106,10 @@
</template>
<template v-if="element.type === 'img-upload'">
<el-upload
:name="element.options.file"
:action="element.options.action"
:accept="element.options.accept"
:file-list="element.options.defaultValue"
:listType="element.options.listType"
:multiple="element.options.multiple"
:limit="element.options.limit"
:disabled="disabled || element.options.disabled"
:on-success="handleUploadSuccess"
>
<el-upload :name="element.options.file" :action="element.options.action" :accept="element.options.accept"
:file-list="element.options.defaultValue" :listType="element.options.listType"
:multiple="element.options.multiple" :limit="element.options.limit"
:disabled="disabled || element.options.disabled" :on-success="handleUploadSuccess">
<SvgIcon v-if="element.options.listType === 'picture-card'" iconClass="insert" />
<el-button v-else>
<SvgIcon iconClass="img-upload" style="margin-right: 10px;" />点击上传
......@@ -205,78 +118,58 @@
</template>
<template v-if="element.type === 'richtext-editor'">
<RichTextEditor
v-model:value="data"
:disable="disabled || element.options.disabled"
:style="{ width: element.options.width }"
/>
<RichTextEditor v-model:value="data" :disable="disabled || element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'cascader'">
<el-cascader
v-model="data"
:options="element.options.remoteOptions"
:placeholder="element.options.placeholder"
:filterable="element.options.filterable"
:clearable="element.options.clearable"
:disabled="disabled || element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-cascader v-model="data" :options="element.options.remoteOptions" :placeholder="element.options.placeholder"
:filterable="element.options.filterable" :clearable="element.options.clearable"
:disabled="disabled || element.options.disabled" :style="{ width: element.options.width }" />
</template>
</el-form-item>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
<script lang="ts" setup>
import { computed, PropType } from 'vue'
import SvgIcon from '../../components/SvgIcon.vue'
import RichTextEditor from '../../components/RichTextEditor.vue'
import { WidgetForm } from '../../config/element'
export default defineComponent({
name: 'ElGenerateFormItem',
components: {
SvgIcon,
RichTextEditor
const props = defineProps({
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
},
props: {
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
},
element: {
type: Object,
required: true
},
model: {
type: Object,
required: true
},
disabled: {
type: Boolean,
required: true
}
element: {
type: Object,
required: true
},
setup(props) {
const data = computed({
get: () => props.model[props.element.model],
set: val => {
// eslint-disable-next-line vue/no-mutating-props
props.model[props.element.model] = val
}
})
const handleFilterOption = (input: string, option: { label: string }) =>
option.label.toLowerCase().includes(input)
const handleUploadSuccess = (_res: any, _file: any, fileList: any[]) => {
data.value = fileList
}
model: {
type: Object,
required: true
},
disabled: {
type: Boolean,
required: true
}
})
return {
data,
handleFilterOption,
handleUploadSuccess
}
const data = computed({
get: () => props.model[props.element.model],
set: val => {
// eslint-disable-next-line vue/no-mutating-props
props.model[props.element.model] = val
}
})
const handleFilterOption = (input: string, option: { label: string }) =>
option.label.toLowerCase().includes(input)
const handleUploadSuccess = (_res: any, _file: any, fileList: any[]) => {
data.value = fileList
}
</script>
......@@ -402,115 +402,95 @@
</el-form>
</template>
<script lang="ts">
import { defineComponent, ref, watch, reactive } from 'vue'
<script lang="ts" setup>
import { ref, watch, reactive } from 'vue'
import Draggable from 'vuedraggable'
import SvgIcon from '../../components/SvgIcon.vue'
import type { FormInstance, FormRules } from 'element-plus'
export default defineComponent({
name: 'ElWidgetConfig',
components: {
Draggable,
SvgIcon
},
props: {
select: {
type: Object
}
},
emits: ['update:select'],
setup(props, context) {
const add = async (formEl: FormInstance | undefined) => {
if (!formEl) return
console.log('sda');
await formEl.validate((valid, fields) => {
if (valid) {
console.log('校验通过');
} else {
console.log('fields', fields);
}
})
}
const data = ref<any>(props.select)
const widgetConfigRef = ref<FormInstance>()
const rules = reactive<FormRules>({
model: [{ required: true, message: '字段标识不为空', trigger: 'blur' }],
dbFieldName: [{ required: true, message: '表字段名称不为空', trigger: 'blur' }],
dbFieldComment: [{ required: true, message: '表字段注释不为空', trigger: 'blur' }]
})
watch(
() => props.select,
(val) => (data.value = val)
)
watch(data, (val) => context.emit('update:select', val), { deep: true })
const hasKey = (key: string) =>
Object.keys(data.value.options).includes(key)
const handleInsertColumn = () => {
data.value.columns.push({
span: 0,
list: []
})
}
const props = defineProps({
select: {
type: Object
}
})
const handleInsertOption = () => {
const index = data.value.options.options.length + 1
data.value.options.options.push({
label: `Option ${index}`,
value: `Option ${index}`
})
}
const emits = defineEmits(['update:select'])
const handleOptionsRemove = (index: number) => {
if (data.value.type === 'grid') {
data.value.columns.splice(index, 1)
} else {
data.value.options.options.splice(index, 1)
}
}
const add = async (formEl: FormInstance | undefined) => {
if (!formEl) return
console.log('sda');
await formEl.validate((valid, fields) => {
if (valid) {
console.log('校验通过');
} else {
console.log('fields', fields);
const handleSliderModeChange = (checked: boolean) => {
checked
? (data.value.options.defaultValue = [10, 90])
: (data.value.options.defaultValue = 0)
}
})
}
const data = ref<any>(props.select)
const widgetConfigRef = ref<FormInstance>()
const rules = reactive<FormRules>({
model: [{ required: true, message: '字段标识不为空', trigger: 'blur' }],
dbFieldName: [{ required: true, message: '表字段名称不为空', trigger: 'blur' }],
dbFieldComment: [{ required: true, message: '表字段注释不为空', trigger: 'blur' }]
})
watch(
() => props.select,
(val) => (data.value = val)
)
watch(data, (val) => emits('update:select', val), { deep: true })
const hasKey = (key: string) =>
Object.keys(data.value.options).includes(key)
const handleInsertColumn = () => {
data.value.columns.push({
span: 0,
list: []
})
}
const handleInsertOption = () => {
const index = data.value.options.options.length + 1
data.value.options.options.push({
label: `Option ${index}`,
value: `Option ${index}`
})
}
const handleOptionsRemove = (index: number) => {
if (data.value.type === 'grid') {
data.value.columns.splice(index, 1)
} else {
data.value.options.options.splice(index, 1)
}
}
const handleSelectModeChange = (val: boolean) => {
if (data.value.type === 'img-upload') {
return
}
if (val) {
if (data.value.options.defaultValue) {
if (!(data.value.options.defaultValue instanceof Array)) {
data.value.options.defaultValue = [data.value.options.defaultValue]
}
} else {
data.value.options.defaultValue = []
}
} else {
data.value.options.defaultValue.length
? (data.value.options.defaultValue =
data.value.options.defaultValue[0])
: (data.value.options.defaultValue = null)
}
}
const handleSliderModeChange = (checked: boolean) => {
checked
? (data.value.options.defaultValue = [10, 90])
: (data.value.options.defaultValue = 0)
}
return {
data,
rules,
widgetConfigRef,
hasKey,
handleInsertColumn,
handleInsertOption,
handleOptionsRemove,
handleSliderModeChange,
handleSelectModeChange,
add
const handleSelectModeChange = (val: boolean) => {
if (data.value.type === 'img-upload') {
return
}
if (val) {
if (data.value.options.defaultValue) {
if (!(data.value.options.defaultValue instanceof Array)) {
data.value.options.defaultValue = [data.value.options.defaultValue]
}
} else {
data.value.options.defaultValue = []
}
} else {
data.value.options.defaultValue.length
? (data.value.options.defaultValue =
data.value.options.defaultValue[0])
: (data.value.options.defaultValue = null)
}
})
}
</script>
<template>
<div class="widget-form-container">
<div v-if="!widgetForm.list" class="form-empty">从左侧拖拽来添加字段</div>
<el-form
label-suffix=":"
:size="widgetForm.config.size"
:label-position="widgetForm.config.labelPosition"
<el-form label-suffix=":" :size="widgetForm.config.size" :label-position="widgetForm.config.labelPosition"
:label-width="`${widgetForm.config.labelWidth}px`"
:hide-required-asterisk="widgetForm.config.hideRequiredAsterisk"
>
<Draggable
class="widget-form-list"
item-key="key"
ghostClass="ghost"
handle=".drag-widget"
:animation="200"
:group="{ name: 'people' }"
:list="widgetForm.list"
@add="handleMoveAdd"
>
:hide-required-asterisk="widgetForm.config.hideRequiredAsterisk">
<Draggable class="widget-form-list" item-key="key" ghostClass="ghost" handle=".drag-widget" :animation="200"
:group="{ name: 'people' }" :list="widgetForm.list" @add="handleMoveAdd">
<template #item="{ element, index }">
<transition-group name="fade" tag="div">
<template v-if="element.type === 'grid'">
<el-row
class="widget-col widget-view"
type="flex"
v-if="element.key"
:key="element.key"
:class="{ active: widgetFormSelect?.key === element.key }"
:gutter="element.options.gutter ?? 0"
:justify="element.options.justify"
:align="element.options.align"
@click="handleItemClick(element)"
>
<el-col
v-for="(col, colIndex) of element.columns"
:key="colIndex"
:span="col.span ?? 0"
>
<Draggable
class="widget-col-list"
item-key="key"
ghostClass="ghost"
handle=".drag-widget"
:animation="200"
:group="{ name: 'people' }"
:no-transition-on-drag="true"
:list="col.list"
@add="handleColMoveAdd($event, element, colIndex)"
>
<el-row class="widget-col widget-view" type="flex" v-if="element.key" :key="element.key"
:class="{ active: widgetFormSelect?.key === element.key }" :gutter="element.options.gutter ?? 0"
:justify="element.options.justify" :align="element.options.align" @click="handleItemClick(element)">
<el-col v-for="(col, colIndex) of element.columns" :key="colIndex" :span="col.span ?? 0">
<Draggable class="widget-col-list" item-key="key" ghostClass="ghost" handle=".drag-widget"
:animation="200" :group="{ name: 'people' }" :no-transition-on-drag="true" :list="col.list"
@add="handleColMoveAdd($event, element, colIndex)">
<template #item="{ element, index }">
<transition-group name="fade" tag="div">
<ElWidgetFormItem
v-if="element.key"
:key="element.key"
:element="element"
:config="widgetForm.config"
:selectWidget="widgetFormSelect"
@click.stop="handleItemClick(element)"
@copy="handleCopyClick(index, col.list)"
@delete="handleDeleteClick(index, col.list)"
/>
<ElWidgetFormItem v-if="element.key" :key="element.key" :element="element"
:config="widgetForm.config" :selectWidget="widgetFormSelect"
@click.stop="handleItemClick(element)" @copy="handleCopyClick(index, col.list)"
@delete="handleDeleteClick(index, col.list)" />
</transition-group>
</template>
</Draggable>
</el-col>
<div
class="widget-view-action widget-col-action"
v-if="widgetFormSelect?.key === element.key"
>
<SvgIcon
iconClass="delete"
@click.stop="handleDeleteClick(index, widgetForm.list)"
/>
<div class="widget-view-action widget-col-action" v-if="widgetFormSelect?.key === element.key">
<SvgIcon iconClass="delete" @click.stop="handleDeleteClick(index, widgetForm.list)" />
</div>
<div
class="widget-view-drag widget-col-drag"
v-if="widgetFormSelect?.key === element.key"
>
<div class="widget-view-drag widget-col-drag" v-if="widgetFormSelect?.key === element.key">
<SvgIcon iconClass="move" className="drag-widget" />
</div>
</el-row>
</template>
<template v-else>
<ElWidgetFormItem
v-if="element.key"
:key="element.key"
:element="element"
:config="widgetForm.config"
:selectWidget="widgetFormSelect"
@click="handleItemClick(element)"
@copy="handleCopyClick(index, widgetForm.list)"
@delete="handleDeleteClick(index, widgetForm.list)"
/>
<ElWidgetFormItem v-if="element.key" :key="element.key" :element="element" :config="widgetForm.config"
:selectWidget="widgetFormSelect" @click="handleItemClick(element)"
@copy="handleCopyClick(index, widgetForm.list)" @delete="handleDeleteClick(index, widgetForm.list)" />
</template>
</transition-group>
</template>
......@@ -101,14 +47,26 @@
</div>
</template>
<script lang="ts">
import { defineComponent, nextTick, PropType } from 'vue'
<script lang="ts" setup>
import { nextTick, PropType } from 'vue'
import Draggable from 'vuedraggable'
import { v4 } from 'uuid'
import ElWidgetFormItem from './ElWidgetFormItem.vue'
import SvgIcon from '../../components/SvgIcon.vue'
import { WidgetForm } from '../../config/element'
const props = defineProps({
widgetForm: {
type: Object as PropType<WidgetForm>,
required: true
},
widgetFormSelect: {
type: Object
}
})
const emits = defineEmits(['update:widgetForm', 'update:widgetFormSelect'])
const handleListInsert = (key: string, list: any[], obj: any) => {
const newList: any[] = []
list.forEach(item => {
......@@ -144,170 +102,142 @@ const handleListDelete = (key: string, list: any[]) => {
return newList
}
export default defineComponent({
name: 'ElWidgetForm',
components: {
SvgIcon,
Draggable,
ElWidgetFormItem
},
props: {
widgetForm: {
type: Object as PropType<WidgetForm>,
required: true
},
widgetFormSelect: {
type: Object
}
},
emits: ['update:widgetForm', 'update:widgetFormSelect'],
setup(props, context) {
const handleItemClick = (row: any) => {
context.emit('update:widgetFormSelect', row)
}
const handleItemClick = (row: any) => {
emits('update:widgetFormSelect', row)
}
const handleCopyClick = (index: number, list: any[]) => {
const key = v4().replaceAll('-', '')
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list))
const handleCopyClick = (index: number, list: any[]) => {
const key = v4().replaceAll('-', '')
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list))
let copyData = {
...list[index],
key,
model: `${list[index].type}_${key}`,
rules: list[index].rules ?? []
}
let copyData = {
...list[index],
key,
model: `${list[index].type}_${key}`,
rules: list[index].rules ?? []
}
if (
list[index].type === 'radio' ||
list[index].type === 'checkbox' ||
list[index].type === 'select'
) {
copyData = {
...copyData,
options: {
...copyData.options,
options: copyData.options.options.map((item: any) => ({ ...item }))
}
}
if (
list[index].type === 'radio' ||
list[index].type === 'checkbox' ||
list[index].type === 'select'
) {
copyData = {
...copyData,
options: {
...copyData.options,
options: copyData.options.options.map((item: any) => ({ ...item }))
}
context.emit('update:widgetForm', {
...props.widgetForm,
list: handleListInsert(list[index].key, oldList, copyData)
})
context.emit('update:widgetFormSelect', copyData)
}
}
emits('update:widgetForm', {
...props.widgetForm,
list: handleListInsert(list[index].key, oldList, copyData)
})
const handleDeleteClick = (index: number, list: any[]) => {
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list))
emits('update:widgetFormSelect', copyData)
}
if (list.length - 1 === index) {
if (index === 0) {
nextTick(() => context.emit('update:widgetFormSelect', null))
} else {
context.emit('update:widgetFormSelect', list[index - 1])
}
} else {
context.emit('update:widgetFormSelect', list[index + 1])
}
const handleDeleteClick = (index: number, list: any[]) => {
const oldList = JSON.parse(JSON.stringify(props.widgetForm.list))
context.emit('update:widgetForm', {
...props.widgetForm,
list: handleListDelete(list[index].key, oldList)
})
if (list.length - 1 === index) {
if (index === 0) {
nextTick(() => emits('update:widgetFormSelect', null))
} else {
emits('update:widgetFormSelect', list[index - 1])
}
} else {
emits('update:widgetFormSelect', list[index + 1])
}
const handleMoveAdd = (event: any) => {
const { newIndex } = event
emits('update:widgetForm', {
...props.widgetForm,
list: handleListDelete(list[index].key, oldList)
})
}
const key = v4().replaceAll('-', '')
const list = JSON.parse(JSON.stringify(props.widgetForm.list))
const handleMoveAdd = (event: any) => {
const { newIndex } = event
list[newIndex] = {
...list[newIndex],
key,
model: `${list[newIndex].type}_${key}`,
rules: []
}
const key = v4().replaceAll('-', '')
const list = JSON.parse(JSON.stringify(props.widgetForm.list))
if (
list[newIndex].type === 'radio' ||
list[newIndex].type === 'checkbox' ||
list[newIndex].type === 'select'
) {
list[newIndex] = {
...list[newIndex],
options: {
...list[newIndex].options,
options: list[newIndex].options.options.map((item: any) => ({
...item
}))
}
}
}
list[newIndex] = {
...list[newIndex],
key,
model: `${list[newIndex].type}_${key}`,
rules: []
}
if (list[newIndex].type === 'grid') {
list[newIndex] = {
...list[newIndex],
columns: list[newIndex].columns.map((item: any) => ({ ...item }))
}
if (
list[newIndex].type === 'radio' ||
list[newIndex].type === 'checkbox' ||
list[newIndex].type === 'select'
) {
list[newIndex] = {
...list[newIndex],
options: {
...list[newIndex].options,
options: list[newIndex].options.options.map((item: any) => ({
...item
}))
}
context.emit('update:widgetForm', { ...props.widgetForm, list })
}
}
context.emit('update:widgetFormSelect', list[newIndex])
if (list[newIndex].type === 'grid') {
list[newIndex] = {
...list[newIndex],
columns: list[newIndex].columns.map((item: any) => ({ ...item }))
}
}
emits('update:widgetForm', { ...props.widgetForm, list })
const handleColMoveAdd = (
event: any,
row: any,
index: string | number | symbol
) => {
const { newIndex, oldIndex, item } = event
const list = JSON.parse(JSON.stringify(props.widgetForm.list))
emits('update:widgetFormSelect', list[newIndex])
}
if (item.className.includes('data-grid')) {
item.tagName === 'DIV' &&
list.splice(oldIndex, 0, row.columns[index].list[newIndex])
row.columns[index].list.splice(newIndex, 1)
return false
}
const handleColMoveAdd = (
event: any,
row: any,
index: string | number | symbol
) => {
const { newIndex, oldIndex, item } = event
const list = JSON.parse(JSON.stringify(props.widgetForm.list))
if (item.className.includes('data-grid')) {
item.tagName === 'DIV' &&
list.splice(oldIndex, 0, row.columns[index].list[newIndex])
row.columns[index].list.splice(newIndex, 1)
return false
}
const key = v4().replaceAll('-', '')
const key = v4().replaceAll('-', '')
row.columns[index].list[newIndex] = {
...row.columns[index].list[newIndex],
key,
model: `${row.columns[index].list[newIndex].type}_${key}`,
rules: []
}
row.columns[index].list[newIndex] = {
...row.columns[index].list[newIndex],
key,
model: `${row.columns[index].list[newIndex].type}_${key}`,
rules: []
}
if (
row.columns[index].list[newIndex].type === 'radio' ||
row.columns[index].list[newIndex].type === 'checkbox' ||
row.columns[index].list[newIndex].type === 'select'
) {
row.columns[index].list[newIndex] = {
...row.columns[index].list[newIndex],
options: {
...row.columns[index].list[newIndex].options,
options: row.columns[index].list[
newIndex
].options.options.map((item: any) => ({ ...item }))
}
}
if (
row.columns[index].list[newIndex].type === 'radio' ||
row.columns[index].list[newIndex].type === 'checkbox' ||
row.columns[index].list[newIndex].type === 'select'
) {
row.columns[index].list[newIndex] = {
...row.columns[index].list[newIndex],
options: {
...row.columns[index].list[newIndex].options,
options: row.columns[index].list[
newIndex
].options.options.map((item: any) => ({ ...item }))
}
context.emit('update:widgetFormSelect', row.columns[index].list[newIndex])
}
return {
handleItemClick,
handleCopyClick,
handleDeleteClick,
handleMoveAdd,
handleColMoveAdd
}
}
})
emits('update:widgetFormSelect', row.columns[index].list[newIndex])
}
</script>
<template>
<div class="widget-item-container">
<el-form-item
class="widget-view"
v-if="element"
:key="element.key"
:class="{ active: selectWidget?.key === element.key }"
:label="element.label"
:rules="element.options.rules"
>
<el-form-item class="widget-view" v-if="element" :key="element.key"
:class="{ active: selectWidget?.key === element.key }" :label="element.label" :rules="element.options.rules">
<template v-if="element.type === 'input'">
<el-input
readonly
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable"
:disabled="element.options.disabled"
>
<el-input readonly :modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:placeholder="element.options.placeholder" :maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable" :disabled="element.options.disabled">
<template #prefix v-if="element.options.prefix">
{{ element.options.prefix }}
</template>
......@@ -34,16 +22,10 @@
</template>
<template v-if="element.type === 'password'">
<el-input
readonly
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable"
:disabled="element.options.disabled"
:show-password="element.options.showPassword"
>
<el-input readonly :modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:placeholder="element.options.placeholder" :maxlength="parseInt(element.options.maxlength)"
:clearable="element.options.clearable" :disabled="element.options.disabled"
:show-password="element.options.showPassword">
<template #prefix v-if="element.options.prefix">
{{ element.options.prefix }}
</template>
......@@ -60,141 +42,75 @@
</template>
<template v-if="element.type === 'textarea'">
<el-input
type="textarea"
resize="none"
readonly
:rows="element.options.rows"
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:placeholder="element.options.placeholder"
:maxlength="parseInt(element.options.maxlength)"
:show-word-limit="element.options.showWordLimit"
:autosize="element.options.autosize"
:clearable="element.options.clearable"
:disabled="element.options.disabled"
/>
<el-input type="textarea" resize="none" readonly :rows="element.options.rows"
:modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:placeholder="element.options.placeholder" :maxlength="parseInt(element.options.maxlength)"
:show-word-limit="element.options.showWordLimit" :autosize="element.options.autosize"
:clearable="element.options.clearable" :disabled="element.options.disabled" />
</template>
<template v-if="element.type === 'number'">
<el-input-number
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:max="element.options.max"
:min="element.options.min"
:disabled="element.options.disabled"
/>
<el-input-number :modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:max="element.options.max" :min="element.options.min" :disabled="element.options.disabled" />
</template>
<template v-if="element.type === 'radio'">
<el-radio-group
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:disabled="element.options.disabled"
>
<el-radio
v-for="item of element.options.options"
:key="item.value"
:label="item.value"
:style="{
display: element.options.inline ? 'inline-block' : 'block'
}"
>{{ element.options.showLabel ? item.label : item.value }}</el-radio
>
<el-radio-group :modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:disabled="element.options.disabled">
<el-radio v-for="item of element.options.options" :key="item.value" :label="item.value" :style="{
display: element.options.inline ? 'inline-block' : 'block'
}">{{ element.options.showLabel ? item.label : item.value }}</el-radio>
</el-radio-group>
</template>
<template v-if="element.type === 'checkbox'">
<el-checkbox-group
:modelValue="element.options.defaultValue"
:style="{ width: element.options.width }"
:disabled="element.options.disabled"
>
<el-checkbox
v-for="item of element.options.options"
:key="item.value"
:label="item.value"
:style="{
display: element.options.inline ? 'inline-block' : 'block'
}"
>{{ element.options.showLabel ? item.label : item.value }}
<el-checkbox-group :modelValue="element.options.defaultValue" :style="{ width: element.options.width }"
:disabled="element.options.disabled">
<el-checkbox v-for="item of element.options.options" :key="item.value" :label="item.value" :style="{
display: element.options.inline ? 'inline-block' : 'block'
}">{{ element.options.showLabel ? item.label : item.value }}
</el-checkbox>
</el-checkbox-group>
</template>
<template v-if="element.type === 'time'">
<el-time-picker
:modelValue="element.options.defaultValue"
:placeholder="element.options.placeholder"
:readonly="element.options.readonly"
:editable="element.options.editable"
:clearable="element.options.clearable"
:format="element.options.format"
:disabled="element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-time-picker :modelValue="element.options.defaultValue" :placeholder="element.options.placeholder"
:readonly="element.options.readonly" :editable="element.options.editable"
:clearable="element.options.clearable" :format="element.options.format" :disabled="element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'date'">
<el-date-picker
:modelValue="element.options.defaultValue"
:placeholder="element.options.placeholder"
:readonly="element.options.readonly"
:editable="element.options.editable"
:clearable="element.options.clearable"
:format="element.options.format"
:disabled="element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-date-picker :modelValue="element.options.defaultValue" :placeholder="element.options.placeholder"
:readonly="element.options.readonly" :editable="element.options.editable"
:clearable="element.options.clearable" :format="element.options.format" :disabled="element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'rate'">
<el-rate
:modelValue="element.options.defaultValue"
:max="element.options.max"
:allowHalf="element.options.allowHalf"
:disabled="element.options.disabled"
/>
<el-rate :modelValue="element.options.defaultValue" :max="element.options.max"
:allowHalf="element.options.allowHalf" :disabled="element.options.disabled" />
</template>
<template v-if="element.type === 'select'">
<el-select
:modelValue="element.options.defaultValue"
:multiple="element.options.multiple"
:placeholder="element.options.placeholder"
:clearable="element.options.clearable"
:filterable="element.options.filterable"
:disabled="element.options.disabled"
:style="{ width: element.options.width }"
>
<el-option
v-for="item of element.options.options"
:key="item.value"
:value="item.value"
:label="element.options.showLabel ? item.label : item.value"
/>
<el-select :modelValue="element.options.defaultValue" :multiple="element.options.multiple"
:placeholder="element.options.placeholder" :clearable="element.options.clearable"
:filterable="element.options.filterable" :disabled="element.options.disabled"
:style="{ width: element.options.width }">
<el-option v-for="item of element.options.options" :key="item.value" :value="item.value"
:label="element.options.showLabel ? item.label : item.value" />
</el-select>
</template>
<template v-if="element.type === 'switch'">
<el-switch
:modelValue="element.options.defaultValue"
:active-text="element.options.activeText"
:inactive-text="element.options.inactiveText"
:disabled="element.options.disabled"
/>
<el-switch :modelValue="element.options.defaultValue" :active-text="element.options.activeText"
:inactive-text="element.options.inactiveText" :disabled="element.options.disabled" />
</template>
<template v-if="element.type === 'slider'">
<el-slider
:modelValue="element.options.defaultValue"
:min="element.options.min"
:max="element.options.max"
:step="element.options.step"
:range="element.options.range"
:disabled="element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-slider :modelValue="element.options.defaultValue" :min="element.options.min" :max="element.options.max"
:step="element.options.step" :range="element.options.range" :disabled="element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type == 'text'">
......@@ -202,20 +118,10 @@
</template>
<template v-if="element.type === 'img-upload'">
<el-upload
:name="element.options.file"
:action="element.options.action"
:accept="element.options.accept"
:file-list="element.options.defaultValue"
:listType="element.options.listType"
:multiple="element.options.multiple"
:limit="element.options.limit"
:disabled="element.options.disabled"
>
<SvgIcon
v-if="element.options.listType === 'picture-card'"
iconClass="insert"
/>
<el-upload :name="element.options.file" :action="element.options.action" :accept="element.options.accept"
:file-list="element.options.defaultValue" :listType="element.options.listType"
:multiple="element.options.multiple" :limit="element.options.limit" :disabled="element.options.disabled">
<SvgIcon v-if="element.options.listType === 'picture-card'" iconClass="insert" />
<el-button v-else>
<SvgIcon iconClass="img-upload" style="margin-right: 10px;" />
点击上传
......@@ -224,23 +130,15 @@
</template>
<template v-if="element.type === 'richtext-editor'">
<RichTextEditor
:value="element.options.defaultValue"
:disable="element.options.disabled"
:style="{ width: element.options.width }"
/>
<RichTextEditor :value="element.options.defaultValue" :disable="element.options.disabled"
:style="{ width: element.options.width }" />
</template>
<template v-if="element.type === 'cascader'">
<el-cascader
:modelValue="element.options.defaultValue"
:options="element.options.remoteOptions"
:placeholder="element.options.placeholder"
:filterable="element.options.filterable"
:clearable="element.options.clearable"
:disabled="element.options.disabled"
:style="{ width: element.options.width }"
/>
<el-cascader :modelValue="element.options.defaultValue" :options="element.options.remoteOptions"
:placeholder="element.options.placeholder" :filterable="element.options.filterable"
:clearable="element.options.clearable" :disabled="element.options.disabled"
:style="{ width: element.options.width }" />
</template>
</el-form-item>
<div class="widget-view-action" v-if="selectWidget?.key === element.key">
......@@ -254,31 +152,26 @@
</div>
</template>
<script lang="ts">
<script lang="ts" setup>
import { defineComponent, PropType } from 'vue'
import SvgIcon from '../../components/SvgIcon.vue'
import RichTextEditor from '../../components/RichTextEditor.vue'
import { WidgetForm } from '../../config/element'
export default defineComponent({
name: 'ElWidgetFormItem',
components: {
SvgIcon,
RichTextEditor
const props = defineProps({
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
},
props: {
config: {
type: Object as PropType<WidgetForm['config']>,
required: true
},
element: {
type: Object,
required: true
},
selectWidget: {
type: Object
}
element: {
type: Object,
required: true
},
emits: ['copy', 'delete']
selectWidget: {
type: Object
}
})
const emits = defineEmits(['copy', 'delete'])
</script>
import { App } from 'vue'
import ElDesignForm from './core/element/ElDesignForm.vue'
import ElDesignForm from './core/element/ElDesignForm.vue' // 主页面
import ElGenerateForm from './core/element/ElGenerateForm.vue'
import Icons from './icons'
import './styles/index.styl'
......@@ -32,5 +32,5 @@ export {
export default {
install,
ElDesignForm,
ElGenerateForm
}
ElGenerateForm,
}
\ No newline at end of file
......@@ -122,6 +122,7 @@ export default ({ command, mode }) => {
},
},
build: {
minify: 'terser',
// 分块打包配置
chunkSizeWarningLimit: 1500, // 分块打包,分解块,将大块分解成更小的块
rollupOptions: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论