|
|
@@ -1,22 +1,16 @@
|
|
|
<script lang="ts" setup>
|
|
|
import type { Ref } from 'vue';
|
|
|
|
|
|
-import type { Recordable } from '@vben/types';
|
|
|
-
|
|
|
import type { IFormConfig, IFormDesignMethods, IVFormComponent } from './types';
|
|
|
|
|
|
-import { onMounted, provide, reactive, ref } from 'vue';
|
|
|
-
|
|
|
-import { cloneDeep } from '@vben/utils';
|
|
|
+import { onMounted, provide, ref } from 'vue';
|
|
|
|
|
|
-import { Card, Collapse, Tabs } from 'ant-design-vue';
|
|
|
+import { Card, Tabs } from 'ant-design-vue';
|
|
|
|
|
|
import ControlConfig from './components/control-config.vue';
|
|
|
-import ControlMark from './components/control-mark.vue';
|
|
|
import FormConfig from './components/form-config.vue';
|
|
|
-import FormEdit from './components/form-edit.vue';
|
|
|
-import { basicControls } from './config/formItemProps';
|
|
|
-import { generateKey } from './utils';
|
|
|
+import FormEdit from './components/form/index.vue';
|
|
|
+import Widget from './components/widget/index.vue';
|
|
|
|
|
|
defineOptions({
|
|
|
name: 'FormDesign',
|
|
|
@@ -31,147 +25,17 @@ const formConfig = ref<IFormConfig>({
|
|
|
},
|
|
|
},
|
|
|
schemas: [],
|
|
|
- currentItem: { component: '' } as IVFormComponent,
|
|
|
-});
|
|
|
-
|
|
|
-const state = reactive<{
|
|
|
- collapseKey: string;
|
|
|
- controlList: Recordable<any>[];
|
|
|
-}>({
|
|
|
- collapseKey: '1',
|
|
|
- controlList: [
|
|
|
- {
|
|
|
- title: '输入型组件',
|
|
|
- fields: ['Input', 'Textarea', 'InputPassword', 'InputNumber'],
|
|
|
- list: basicControls,
|
|
|
- },
|
|
|
- ],
|
|
|
+ selectSchema: { component: '' } as IVFormComponent,
|
|
|
});
|
|
|
|
|
|
-/**
|
|
|
- * 选中表单项
|
|
|
- * @param schema 当前选中的表单项
|
|
|
- */
|
|
|
-const handleSetSelectItem = (schema: IVFormComponent) => {
|
|
|
- formConfig.value.currentItem = schema as any;
|
|
|
- // handleChangePropsTabs(
|
|
|
- // schema.key ? (formConfig.value.activeKey! === 1 ? 2 : formConfig.value.activeKey!) : 1,
|
|
|
- // );
|
|
|
+const setSelectSchema = (schema: IVFormComponent) => {
|
|
|
+ formConfig.value.selectSchema = schema as any;
|
|
|
};
|
|
|
|
|
|
-const setGlobalConfigState = (formItem: IVFormComponent) => {
|
|
|
- // formItem.colProps = formItem.colProps || {};
|
|
|
- // formItem.colProps.span = globalConfigState.span;
|
|
|
- formItem.aaa = '';
|
|
|
- // console.log('setGlobalConfigState', formItem);
|
|
|
-};
|
|
|
-
|
|
|
-// 把表单配置项注入到子组件中,子组件可通过inject获取,获取到的数据为响应式
|
|
|
provide<Ref<IFormConfig>>('formConfig', formConfig as any);
|
|
|
|
|
|
-/**
|
|
|
- * 添加属性
|
|
|
- * @param schemas
|
|
|
- * @param index
|
|
|
- */
|
|
|
-const handleAddAttrs = (_formItems: IVFormComponent[], _index: number) => {};
|
|
|
-
|
|
|
-const handleListPushDrag = (item: IVFormComponent) => {
|
|
|
- const formItem = cloneDeep(item);
|
|
|
- setGlobalConfigState(formItem);
|
|
|
- generateKey(formItem);
|
|
|
-
|
|
|
- return formItem;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 添加到表单中
|
|
|
- * @param newIndex {object} 事件对象
|
|
|
- * @param schemas {IVFormComponent[]} 表单项列表
|
|
|
- * @param isCopy {boolean} 是否复制
|
|
|
- */
|
|
|
-const handleBeforeColAdd = (
|
|
|
- { newIndex }: any,
|
|
|
- schemas: IVFormComponent[],
|
|
|
- isCopy = false,
|
|
|
-) => {
|
|
|
- const item = schemas[newIndex] as IVFormComponent;
|
|
|
- isCopy && generateKey(item);
|
|
|
- handleSetSelectItem(item);
|
|
|
-};
|
|
|
-/**
|
|
|
- * 复制表单项,如果表单项为栅格布局,则遍历所有自表单项重新生成key
|
|
|
- * @param {IVFormComponent} formItem
|
|
|
- * @return {IVFormComponent}
|
|
|
- */
|
|
|
-const copyFormItem = (formItem: IVFormComponent) => {
|
|
|
- const newFormItem = cloneDeep(formItem);
|
|
|
- // if (newFormItem.component === 'Grid') {
|
|
|
- // formItemsForEach([formItem], (item) => {
|
|
|
- // generateKey(item);
|
|
|
- // });
|
|
|
- // }
|
|
|
- return newFormItem;
|
|
|
-};
|
|
|
-/**
|
|
|
- * 复制或者添加表单,isCopy为true时则复制表单
|
|
|
- * @param item {IVFormComponent} 当前点击的组件
|
|
|
- * @param isCopy {boolean} 是否复制
|
|
|
- */
|
|
|
-const handleCopy = (
|
|
|
- item: IVFormComponent = formConfig.value.currentItem as IVFormComponent,
|
|
|
- isCopy = true,
|
|
|
-) => {
|
|
|
- const key = formConfig.value.currentItem?.key;
|
|
|
- /**
|
|
|
- * 遍历当表单项配置,如果是复制,则复制一份表单项,如果不是复制,则直接添加到表单项中
|
|
|
- * @param schemas
|
|
|
- */
|
|
|
- const traverse = (schemas: IVFormComponent[]) => {
|
|
|
- // 使用some遍历,找到目标后停止遍历
|
|
|
- schemas.some((formItem: IVFormComponent, index: number) => {
|
|
|
- if (formItem.key === key) {
|
|
|
- // 判断是不是复制
|
|
|
- isCopy
|
|
|
- ? schemas.splice(index, 0, copyFormItem(formItem))
|
|
|
- : schemas.splice(index + 1, 0, item);
|
|
|
- const event = {
|
|
|
- newIndex: index + 1,
|
|
|
- };
|
|
|
- // 添加到表单项中
|
|
|
- handleBeforeColAdd(event, schemas, isCopy);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- });
|
|
|
- };
|
|
|
- if (formConfig.value.schemas) {
|
|
|
- traverse(formConfig.value.schemas as any);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 单击控件时添加到面板中
|
|
|
- * @param item {IVFormComponent} 当前点击的组件
|
|
|
- */
|
|
|
-const handleListPush = (item: IVFormComponent) => {
|
|
|
- // console.log('handleListPush', item);
|
|
|
- const formItem = cloneDeep(item);
|
|
|
- setGlobalConfigState(formItem);
|
|
|
- generateKey(formItem);
|
|
|
- if (!formConfig.value.currentItem?.key) {
|
|
|
- handleSetSelectItem(formItem);
|
|
|
- formConfig.value.schemas && formConfig.value.schemas.push(formItem as any);
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
- handleCopy(formItem, false);
|
|
|
-};
|
|
|
-
|
|
|
-// 把祖先组件的方法项注入到子组件中,子组件可通过inject获取
|
|
|
provide<IFormDesignMethods>('formDesignMethods', {
|
|
|
- handleAddAttrs,
|
|
|
- handleSetSelectItem,
|
|
|
+ setSelectSchema,
|
|
|
});
|
|
|
|
|
|
onMounted(async () => {});
|
|
|
@@ -179,34 +43,11 @@ onMounted(async () => {});
|
|
|
<template>
|
|
|
<div class="flex h-full w-full">
|
|
|
<div class="w-[300px]">
|
|
|
- <Collapse
|
|
|
- :bordered="false"
|
|
|
- ghost
|
|
|
- expand-icon-position="end"
|
|
|
- v-model:active-key="state.collapseKey"
|
|
|
- >
|
|
|
- <Collapse.Panel
|
|
|
- v-for="(item, index) in state.controlList"
|
|
|
- :key="index + 1"
|
|
|
- :header="item.title"
|
|
|
- >
|
|
|
- <ControlMark
|
|
|
- :fields="item.fields"
|
|
|
- :list="item.list"
|
|
|
- @add-attrs="handleAddAttrs"
|
|
|
- :handle-list-push="handleListPushDrag"
|
|
|
- @handle-list-push="handleListPush"
|
|
|
- />
|
|
|
- </Collapse.Panel>
|
|
|
- </Collapse>
|
|
|
+ <Widget />
|
|
|
</div>
|
|
|
<div class="h-full flex-1 pl-2 pr-2">
|
|
|
<Card title="设计区域" class="h-full w-full">
|
|
|
- <FormEdit
|
|
|
- :form-config="formConfig"
|
|
|
- :form-config-select="formConfig.currentItem"
|
|
|
- @change="handleSetSelectItem"
|
|
|
- />
|
|
|
+ <FormEdit />
|
|
|
</Card>
|
|
|
</div>
|
|
|
<div class="w-[300px]">
|