123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <template>
- <section h-full bg-white flex>
- <aside pt-2 w-62>
- <ComponentGroup
- title="基础字段"
- :fields="basicFieldsList"
- :list="basicComponents"
- :allList="widgetForm"
- />
- <ComponentGroup
- title="高级字段"
- :fields="advanceFieldsList"
- :list="advanceComponents"
- :allList="widgetForm"
- />
- <ComponentGroup
- title="布局字段"
- :fields="layoutFieldsList"
- :list="layoutComponents"
- :allList="widgetForm"
- />
- </aside>
- <main border="0 x solid gray-200" flex="~ 1 col nowrap">
- <header border="0 b solid gray-200" flex gap-2 items-center justify-end h-11 py-0 px-2>
- <slot />
- <el-button v-if="generateJson" type="text" @click="handleGenerateJson">
- <template #icon>
- <i class="ep:edit" />
- </template>修改
- </el-button>
- <el-button v-if="clearable" type="text" @click="handleClearable">
- <template #icon>
- <i class="custom:clearable" />
- </template>清空
- </el-button>
- <el-button v-if="preview" type="text" @click="previewVisible = true">
- <template #icon>
- <i class="custom:preview" />
- </template>预览
- </el-button>
- </header>
- <WidgetFormVue
- ref="widgetFormRef"
- v-bind="widgetForm"
- v-model:selectWidget="selectWidget"
- />
- </main>
- <aside relative w-75 flex="~ col">
- <header border="0 b-1 gray-200" grid="~ cols-2" min-h-11 px-2>
- <div :class="[{active:!tab}, 'config-tab']" @click="tab = 0">
- 字段属性
- </div>
- <div :class="[{active:tab}, 'config-tab']" @click="tab = 1">
- 表单属性
- </div>
- </header>
- <WidgetConfig
- v-show="!tab"
- v-model:select="selectWidget"
- />
- <FormConfig
- v-show="tab"
- v-model:config="widgetForm.config"
- />
- </aside>
- <el-dialog v-model="previewVisible" destroy-on-close title="预览" :z-index="2000" :width="800" @close="dataVisible=false">
- <CodeEditor v-show="dataVisible" v-model="generateJsonTemplate" />
- <GenerateForm
- v-show="!dataVisible"
- ref="generateFormRef"
- :request="request"
- :data="widgetForm"
- />
- <template #footer>
- <el-button @click="dataVisible?handleCopyClick(generateJsonTemplate):handleReset()">
- {{ dataVisible?'复制':'重置' }}
- </el-button>
- <el-button type="primary" @click="handleGetData">
- {{ dataVisible?'返回预览':'获取数据' }}
- </el-button>
- </template>
- </el-dialog>
- <el-dialog v-model="generateJsonVisible" append-to-body title="修改JSON" :z-index="20000" :width="800">
- <CodeEditor v-model="generateJsonTemplate" />
- <template #footer>
- <el-button @click="handleCopyClick(generateJsonTemplate)">
- 复制
- </el-button>
- <el-button type="primary" @click="handleUploadJson">
- 确认修改
- </el-button>
- </template>
- </el-dialog>
- </section>
- </template>
- <script lang="ts" setup>
- import type { PropType } from 'vue'
- import { ElMessage } from 'element-plus'
- // eslint-disable-next-line @typescript-eslint/consistent-type-imports
- import GenerateForm from '../generate/GenerateForm.vue'
- import WidgetFormVue from './WidgetForm.vue'
- import WidgetConfig from './WidgetConfig.vue'
- import FormConfig from './FormConfig.vue'
- import ComponentGroup from '@/components/ComponentGroup.vue'
- import CodeEditor from '@/components/CodeEditor.vue'
- import type { WidgetForm } from '@/config'
- import { advanceComponents, advanceFields, basicComponents, basicFields, getWidgetForm, layoutComponents, layoutFields } from '@/config'
- defineOptions({ name: 'DesignForm' })
- defineProps({
- preview: {
- type: Boolean,
- default: true,
- },
- generateJson: {
- type: Boolean,
- default: true,
- },
- clearable: {
- type: Boolean,
- default: true,
- },
- basicFieldsList: {
- type: Array as PropType<typeof basicFields>,
- default: () => basicFields,
- },
- advanceFieldsList: {
- type: Array as PropType<typeof advanceFields>,
- default: () => advanceFields,
- },
- layoutFieldsList: {
- type: Array as PropType<typeof layoutFields>,
- default: () => layoutFields,
- },
- request: {
- type: Function,
- },
- })
- let tab = $ref(0)
- let selectWidget = $ref<any>()
- watch(() => selectWidget, (val) => {
- tab = val ? 0 : 1
- })
- let widgetForm = $ref(getWidgetForm())
- let generateJsonVisible = $ref(false)
- let generateJsonTemplate = $ref(JSON.stringify(getWidgetForm(), null, 2))
- const handleUploadJson = () => {
- try {
- widgetForm = JSON.parse(generateJsonTemplate)
- selectWidget = widgetForm.list?.[0]
- generateJsonVisible = false
- ElMessage.success('修改成功')
- }
- catch (error) {
- ElMessage.error('修改失败,请检查JSON格式是否正确。')
- }
- }
- const handleGenerateJson = () =>
- (generateJsonTemplate = JSON.stringify(widgetForm, null, 2))
- && (generateJsonVisible = true)
- const handleClearable = () => {
- widgetForm = getWidgetForm()
- selectWidget = undefined
- }
- let dataVisible = $ref(false)
- const generateFormRef = $ref<InstanceType<typeof GenerateForm>|null>(null)
- const handleGetData = async() => {
- dataVisible = !dataVisible
- if (!dataVisible) return
- const res = await generateFormRef?.getData()
- generateJsonTemplate = JSON.stringify(res, null, 2)
- }
- const handleReset = () => generateFormRef?.reset()
- const handleCopyClick = (text: string) => {
- navigator.clipboard.writeText(text)
- ElMessage.success({ message: 'Copy成功' })
- }
- const previewVisible = $ref(false)
- defineExpose({
- getJson: () => $$(widgetForm).value,
- setJson: (json: WidgetForm) => {
- widgetForm = json
- selectWidget = json.list?.[0]
- },
- clear: handleClearable,
- })
- </script>
- <style lang="scss">
- .config-tab {
- @apply cursor-pointer text-sm text-gray-700
- flex items-center justify-center
- border-0 border-b-2 border-white;
- &.active {
- @apply border-blue-500;
- }
- }
- </style>
|