Commit 84c9d78fa7feffe3430b7c85dc97383cd7193ba1

Authored by vben
1 parent e2333642

refactor(form): code optimization and reconstruction

CHANGELOG.zh_CN.md
1 1 ## Wip
2 2  
  3 +### ✨ Features
  4 +
  5 +- 表单组件现在支持直接传入 model 直接进行 set 操作,参考**组件->弹窗扩展->打开弹窗并传递数据**
  6 +
  7 +- modal 的 useModalInner 现在支持传入回调函数,用于接收外部`transferModalData`传进来的值,
  8 + - 用于处理打开弹窗对表单等组件的设置值。参考**组件->弹窗扩展->打开弹窗并传递数据**
  9 + - `receiveModalDataRef`这个值暂时保留。尽量少用。后续可能会删除。
  10 +
  11 +### ✨ Refactor
  12 +
  13 +- 表单代码优化重构
  14 +
3 15 ### 🎫 Chores
4 16  
5 17 - 添加部分注释
... ... @@ -10,6 +22,7 @@
10 22  
11 23 - 修复本地代理 post 接口到 https 地址超时错误
12 24 - 修复 modal 在不显示 footer 的时候全屏高度计算问题
  25 +- 修复表单重置未删除校验信息错误
13 26  
14 27 ## 2.0.0-rc.6 (2020-10-28)
15 28  
... ...
src/components/Form/src/BasicForm.vue
... ... @@ -25,6 +25,8 @@
25 25 <script lang="ts">
26 26 import type { FormActionType, FormProps, FormSchema } from './types/form';
27 27 import type { Form as FormType, ValidateFields } from 'ant-design-vue/types/form/form';
  28 + import type { AdvanceState } from './types/hooks';
  29 + import type { Ref } from 'vue';
28 30  
29 31 import {
30 32 defineComponent,
... ... @@ -32,27 +34,22 @@
32 34 ref,
33 35 computed,
34 36 unref,
35   - toRaw,
36   - watch,
37 37 toRef,
38 38 onMounted,
  39 + watchEffect,
39 40 } from 'vue';
40 41 import { Form, Row } from 'ant-design-vue';
41 42 import FormItem from './FormItem';
42 43 import { basicProps } from './props';
43   - import { deepMerge, unique } from '/@/utils';
  44 + import { deepMerge } from '/@/utils';
44 45 import FormAction from './FormAction';
45 46  
46 47 import { dateItemType } from './helper';
47 48 import moment from 'moment';
48   - import { isArray, isBoolean, isFunction, isNumber, isObject, isString } from '/@/utils/is';
49 49 import { cloneDeep } from 'lodash-es';
50   - import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
51   - // import { useThrottle } from '/@/hooks/core/useThrottle';
52 50 import { useFormValues } from './hooks/useFormValues';
53   - import type { ColEx } from './types';
54   - import { NamePath } from 'ant-design-vue/types/form/form-item';
55   - const BASIC_COL_LEN = 24;
  51 + import useAdvanced from './hooks/useAdvanced';
  52 + import { useFormAction } from './hooks/useFormAction';
56 53  
57 54 export default defineComponent({
58 55 name: 'BasicForm',
... ... @@ -61,13 +58,20 @@
61 58 props: basicProps,
62 59 emits: ['advanced-change', 'reset', 'submit', 'register'],
63 60 setup(props, { emit }) {
64   - let formModel = reactive({});
65   - const advanceState = reactive({
  61 + const formModel = reactive({});
  62 +
  63 + const actionState = reactive({
  64 + resetAction: {},
  65 + submitAction: {},
  66 + });
  67 +
  68 + const advanceState = reactive<AdvanceState>({
66 69 isAdvanced: true,
67 70 hideAdvanceBtn: false,
68 71 isLoad: false,
69 72 actionSpan: 6,
70 73 });
  74 +
71 75 const defaultValueRef = ref<any>({});
72 76 const propsRef = ref<Partial<FormProps>>({});
73 77 const schemaRef = ref<FormSchema[] | null>(null);
... ... @@ -78,50 +82,24 @@
78 82 return deepMerge(cloneDeep(props), unref(propsRef));
79 83 }
80 84 );
  85 +
81 86 // 获取表单基本配置
82 87 const getProps = computed(
83 88 (): FormProps => {
84   - const resetAction = {
85   - onClick: resetFields,
86   - };
87   - const submitAction = {
88   - onClick: handleSubmit,
89   - };
90 89 return {
91 90 ...unref(getMergePropsRef),
92 91 resetButtonOptions: deepMerge(
93   - resetAction,
  92 + actionState.resetAction,
94 93 unref(getMergePropsRef).resetButtonOptions || {}
95   - ) as any,
  94 + ),
96 95 submitButtonOptions: deepMerge(
97   - submitAction,
  96 + actionState.submitAction,
98 97 unref(getMergePropsRef).submitButtonOptions || {}
99   - ) as any,
  98 + ),
100 99 };
101 100 }
102 101 );
103 102  
104   - const getActionPropsRef = computed(() => {
105   - const {
106   - resetButtonOptions,
107   - submitButtonOptions,
108   - showActionButtonGroup,
109   - showResetButton,
110   - showSubmitButton,
111   - showAdvancedButton,
112   - actionColOptions,
113   - } = unref(getProps);
114   - return {
115   - resetButtonOptions,
116   - submitButtonOptions,
117   - show: showActionButtonGroup,
118   - showResetButton,
119   - showSubmitButton,
120   - showAdvancedButton,
121   - actionColOptions,
122   - };
123   - });
124   -
125 103 const getSchema = computed((): FormSchema[] => {
126 104 const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any);
127 105 for (const schema of schemas) {
... ... @@ -133,305 +111,51 @@
133 111 return schemas as FormSchema[];
134 112 });
135 113  
136   - const getEmptySpanRef = computed((): number => {
137   - if (!advanceState.isAdvanced) {
138   - return 0;
139   - }
140   - const emptySpan = unref(getMergePropsRef).emptySpan || 0;
141   -
142   - if (isNumber(emptySpan)) {
143   - return emptySpan;
144   - }
145   - if (isObject(emptySpan)) {
146   - const { span = 0 } = emptySpan;
147   - const screen = unref(screenRef) as string;
148   -
149   - const screenSpan = (emptySpan as any)[screen.toLowerCase()];
150   - return screenSpan || span || 0;
151   - }
152   - return 0;
  114 + const { getActionPropsRef, handleToggleAdvanced } = useAdvanced({
  115 + advanceState,
  116 + emit,
  117 + getMergePropsRef,
  118 + getProps,
  119 + getSchema,
  120 + formModel,
  121 + defaultValueRef,
153 122 });
154 123  
155   - const { realWidthRef, screenEnum, screenRef } = useBreakpoint();
156   - // const [throttleUpdateAdvanced] = useThrottle(updateAdvanced, 30, { immediate: true });
157   - watch(
158   - [() => unref(getSchema), () => advanceState.isAdvanced, () => unref(realWidthRef)],
159   - () => {
160   - const { showAdvancedButton } = unref(getProps);
161   - if (showAdvancedButton) {
162   - updateAdvanced();
163   - }
164   - },
165   - { immediate: true }
166   - );
167   -
168   - function initDefault() {
169   - const schemas = unref(getSchema);
170   - const obj: any = {};
171   - schemas.forEach((item) => {
172   - if (item.defaultValue) {
173   - obj[item.field] = item.defaultValue;
174   - (formModel as any)[item.field] = item.defaultValue;
175   - }
176   - });
177   - defaultValueRef.value = obj;
178   - }
179   -
180   - function updateAdvanced() {
181   - let itemColSum = 0;
182   - let realItemColSum = 0;
183   - for (const schema of unref(getSchema)) {
184   - const { show, colProps } = schema;
185   - let isShow = true;
186   -
187   - if (isBoolean(show)) {
188   - isShow = show;
189   - }
190   -
191   - if (isFunction(show)) {
192   - isShow = show({
193   - schema: schema,
194   - model: formModel,
195   - field: schema.field,
196   - values: {
197   - ...unref(defaultValueRef),
198   - ...formModel,
199   - },
200   - });
201   - }
202   - if (isShow && colProps) {
203   - const { itemColSum: sum, isAdvanced } = getAdvanced(colProps, itemColSum);
204   -
205   - itemColSum = sum || 0;
206   - if (isAdvanced) {
207   - realItemColSum = itemColSum;
208   - }
209   - schema.isAdvanced = isAdvanced;
210   - }
211   - }
212   - advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpanRef);
213   - getAdvanced(
214   - unref(getActionPropsRef).actionColOptions || { span: BASIC_COL_LEN },
215   - itemColSum,
216   - true
217   - );
218   - emit('advanced-change');
219   - }
220   - function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
221   - const width = unref(realWidthRef);
222   -
223   - const mdWidth =
224   - parseInt(itemCol.md as string) ||
225   - parseInt(itemCol.xs as string) ||
226   - parseInt(itemCol.sm as string) ||
227   - (itemCol.span as number) ||
228   - BASIC_COL_LEN;
229   - const lgWidth = parseInt(itemCol.lg as string) || mdWidth;
230   - const xlWidth = parseInt(itemCol.xl as string) || lgWidth;
231   - const xxlWidth = parseInt(itemCol.xxl as string) || xlWidth;
232   - if (width <= screenEnum.LG) {
233   - itemColSum += mdWidth;
234   - } else if (width < screenEnum.XL) {
235   - itemColSum += lgWidth;
236   - } else if (width < screenEnum.XXL) {
237   - itemColSum += xlWidth;
238   - } else {
239   - itemColSum += xxlWidth;
240   - }
241   - if (isLastAction) {
242   - advanceState.hideAdvanceBtn = false;
243   - if (itemColSum <= BASIC_COL_LEN * 2) {
244   - // 小于等于2行时,不显示收起展开按钮
245   - advanceState.hideAdvanceBtn = true;
246   - advanceState.isAdvanced = true;
247   - } else if (
248   - itemColSum > BASIC_COL_LEN * 2 &&
249   - itemColSum <= BASIC_COL_LEN * (props.autoAdvancedLine || 3)
250   - ) {
251   - advanceState.hideAdvanceBtn = false;
252   -
253   - // 大于3行默认收起
254   - } else if (!advanceState.isLoad) {
255   - advanceState.isLoad = true;
256   - advanceState.isAdvanced = !advanceState.isAdvanced;
257   - }
258   - return { isAdvanced: advanceState.isAdvanced, itemColSum };
259   - }
260   - if (itemColSum > BASIC_COL_LEN) {
261   - return { isAdvanced: advanceState.isAdvanced, itemColSum };
262   - } else {
263   - // 第一行始终显示
264   - return { isAdvanced: true, itemColSum };
265   - }
266   - }
267   -
268   - async function resetFields(): Promise<any> {
269   - const { resetFunc, submitOnReset } = unref(getProps);
270   - resetFunc && isFunction(resetFunc) && (await resetFunc());
271   - const formEl = unref(formElRef);
272   - if (!formEl) return;
273   - Object.keys(formModel).forEach((key) => {
274   - (formModel as any)[key] = defaultValueRef.value[key];
275   - });
276   - // const values = formEl.resetFields();
277   - emit('reset', toRaw(formModel));
278   - // return values;
279   - submitOnReset && handleSubmit();
280   - }
281   -
282   - /**
283   - * @description: 设置表单值
284   - */
285   - async function setFieldsValue(values: any): Promise<void> {
286   - const fields = unref(getSchema)
287   - .map((item) => item.field)
288   - .filter(Boolean);
289   - const formEl = unref(formElRef);
290   - Object.keys(values).forEach((key) => {
291   - const element = values[key];
292   - if (fields.includes(key) && element !== undefined && element !== null) {
293   - // 时间
294   - if (itemIsDateType(key)) {
295   - if (Array.isArray(element)) {
296   - const arr: any[] = [];
297   - for (const ele of element) {
298   - arr.push(moment(ele));
299   - }
300   - (formModel as any)[key] = arr;
301   - } else {
302   - (formModel as any)[key] = moment(element);
303   - }
304   - } else {
305   - (formModel as any)[key] = element;
306   - }
307   - if (formEl) {
308   - formEl.validateFields([key]);
309   - }
310   - }
311   - });
312   - }
313   -
314   - /**
315   - * @description: 表单提交
316   - */
317   - async function handleSubmit(e?: Event): Promise<void> {
318   - e && e.preventDefault();
319   - const { submitFunc } = unref(getProps);
320   - if (submitFunc && isFunction(submitFunc)) {
321   - await submitFunc();
322   - return;
323   - }
324   - const formEl = unref(formElRef);
325   - if (!formEl) return;
326   - try {
327   - const values = await formEl.validate();
328   - const res = handleFormValues(values);
329   - emit('submit', res);
330   - } catch (error) {}
331   - }
332   -
333   - /**
334   - * @description: 根据字段名删除
335   - */
336   - function removeSchemaByFiled(fields: string | string[]): void {
337   - const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
338   - if (!fields) {
339   - return;
340   - }
341   - let fieldList: string[] = fields as string[];
342   - if (isString(fields)) {
343   - fieldList = [fields];
344   - }
345   - for (const field of fieldList) {
346   - _removeSchemaByFiled(field, schemaList);
347   - }
348   - schemaRef.value = schemaList as any;
349   - }
350   -
351   - /**
352   - * @description: 根据字段名删除
353   - */
354   - function _removeSchemaByFiled(field: string, schemaList: FormSchema[]): void {
355   - if (isString(field)) {
356   - const index = schemaList.findIndex((schema) => schema.field === field);
357   - if (index !== -1) {
358   - schemaList.splice(index, 1);
359   - }
360   - }
361   - }
362   -
363   - /**
364   - * @description: 往某个字段后面插入,如果没有插入最后一个
365   - */
366   - function appendSchemaByField(schema: FormSchema, prefixField?: string) {
367   - const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
368   -
369   - const index = schemaList.findIndex((schema) => schema.field === prefixField);
370   - const hasInList = schemaList.find((item) => item.field === schema.field);
371   -
372   - if (hasInList) {
373   - return;
374   - }
375   - if (!prefixField || index === -1) {
376   - schemaList.push(schema);
377   - schemaRef.value = schemaList as any;
378   - return;
379   - }
380   - if (index !== -1) {
381   - schemaList.splice(index + 1, 0, schema);
382   - }
383   - schemaRef.value = schemaList as any;
384   - }
385   -
386   - function updateSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
387   - let updateData: Partial<FormSchema>[] = [];
388   - if (isObject(data)) {
389   - updateData.push(data as FormSchema);
390   - }
391   - if (isArray(data)) {
392   - updateData = [...data];
393   - }
394   - const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
395   - if (!hasField) {
396   - throw new Error('Must pass in the `field` field!');
397   - }
398   - const schema: FormSchema[] = [];
399   - updateData.forEach((item) => {
400   - unref(getSchema).forEach((val) => {
401   - if (val.field === item.field) {
402   - const newScheam = deepMerge(val, item);
403   - schema.push(newScheam as FormSchema);
404   - } else {
405   - schema.push(val);
406   - }
407   - });
408   - });
409   - schemaRef.value = unique(schema, 'field') as any;
410   - }
411   -
412   - function handleToggleAdvanced() {
413   - advanceState.isAdvanced = !advanceState.isAdvanced;
414   - }
415   -
416   - const handleFormValues = useFormValues(
417   - toRef(props, 'transformDateFunc'),
418   - toRef(props, 'fieldMapToTime')
419   - );
  124 + const { handleFormValues, initDefault } = useFormValues({
  125 + transformDateFuncRef: toRef(props, 'transformDateFunc') as Ref<Fn<any>>,
  126 + fieldMapToTimeRef: toRef(props, 'fieldMapToTime'),
  127 + defaultValueRef,
  128 + getSchema,
  129 + formModel,
  130 + });
420 131  
421   - function getFieldsValue(): any {
422   - const formEl = unref(formElRef);
423   - if (!formEl) return;
424   - return handleFormValues(toRaw(unref(formModel)));
425   - }
  132 + const {
  133 + // handleSubmit,
  134 + setFieldsValue,
  135 + clearValidate,
  136 + validate,
  137 + validateFields,
  138 + getFieldsValue,
  139 + updateSchema,
  140 + appendSchemaByField,
  141 + removeSchemaByFiled,
  142 + resetFields,
  143 + } = useFormAction({
  144 + emit,
  145 + getProps,
  146 + formModel,
  147 + getSchema,
  148 + defaultValueRef,
  149 + formElRef: formElRef as any,
  150 + schemaRef: schemaRef as any,
  151 + handleFormValues,
  152 + actionState,
  153 + });
426 154  
427   - /**
428   - * @description: 是否是时间
429   - */
430   - function itemIsDateType(key: string) {
431   - return unref(getSchema).some((item) => {
432   - return item.field === key ? dateItemType.includes(item.component!) : false;
433   - });
434   - }
  155 + watchEffect(() => {
  156 + if (!unref(getMergePropsRef).model) return;
  157 + setFieldsValue(unref(getMergePropsRef).model);
  158 + });
435 159  
436 160 /**
437 161 * @description:设置表单
... ... @@ -441,21 +165,6 @@
441 165 propsRef.value = mergeProps;
442 166 }
443 167  
444   - function validateFields(nameList?: NamePath[] | undefined) {
445   - if (!formElRef.value) return;
446   - return formElRef.value.validateFields(nameList);
447   - }
448   -
449   - function validate(nameList?: NamePath[] | undefined) {
450   - if (!formElRef.value) return;
451   - return formElRef.value.validate(nameList);
452   - }
453   -
454   - function clearValidate(name: string | string[]) {
455   - if (!formElRef.value) return;
456   - formElRef.value.clearValidate(name);
457   - }
458   -
459 168 const methods: Partial<FormActionType> = {
460 169 getFieldsValue,
461 170 setFieldsValue,
... ...
src/components/Form/src/FormAction.tsx
... ... @@ -57,6 +57,7 @@ export default defineComponent({
57 57 ...props.resetButtonOptions,
58 58 };
59 59 });
  60 +
60 61 const getSubmitBtnOptionsRef = computed(() => {
61 62 return {
62 63 text: '查询',
... ... @@ -80,10 +81,12 @@ export default defineComponent({
80 81 function toggleAdvanced() {
81 82 emit('toggle-advanced');
82 83 }
  84 +
83 85 return () => {
84 86 if (!props.show) {
85 87 return;
86 88 }
  89 +
87 90 const {
88 91 showAdvancedButton,
89 92 hideAdvanceBtn,
... ... @@ -91,50 +94,49 @@ export default defineComponent({
91 94 showResetButton,
92 95 showSubmitButton,
93 96 } = props;
  97 +
94 98 return (
95   - <>
96   - <Col {...unref(actionColOpt)} style={{ textAlign: 'right' }}>
97   - {() => (
98   - <Form.Item>
99   - {() => (
100   - <>
101   - {getSlot(slots, 'advanceBefore')}
102   - {showAdvancedButton && !hideAdvanceBtn && (
103   - <Button type="default" class="mr-2" onClick={toggleAdvanced}>
104   - {() => (
105   - <>
106   - {isAdvanced ? '收起' : '展开'}
107   - {isAdvanced ? (
108   - <UpOutlined class="advanced-icon" />
109   - ) : (
110   - <DownOutlined class="advanced-icon" />
111   - )}
112   - </>
113   - )}
114   - </Button>
115   - )}
  99 + <Col {...unref(actionColOpt)} style={{ textAlign: 'right' }}>
  100 + {() => (
  101 + <Form.Item>
  102 + {() => (
  103 + <>
  104 + {getSlot(slots, 'advanceBefore')}
  105 + {showAdvancedButton && !hideAdvanceBtn && (
  106 + <Button type="default" class="mr-2" onClick={toggleAdvanced}>
  107 + {() => (
  108 + <>
  109 + {isAdvanced ? '收起' : '展开'}
  110 + {isAdvanced ? (
  111 + <UpOutlined class="advanced-icon" />
  112 + ) : (
  113 + <DownOutlined class="advanced-icon" />
  114 + )}
  115 + </>
  116 + )}
  117 + </Button>
  118 + )}
116 119  
117   - {getSlot(slots, 'resetBefore')}
118   - {showResetButton && (
119   - <Button type="default" class="mr-2" {...unref(getResetBtnOptionsRef)}>
120   - {() => unref(getResetBtnOptionsRef).text}
121   - </Button>
122   - )}
  120 + {getSlot(slots, 'resetBefore')}
  121 + {showResetButton && (
  122 + <Button type="default" class="mr-2" {...unref(getResetBtnOptionsRef)}>
  123 + {() => unref(getResetBtnOptionsRef).text}
  124 + </Button>
  125 + )}
123 126  
124   - {getSlot(slots, 'submitBefore')}
125   - {showSubmitButton && (
126   - <Button type="primary" {...unref(getSubmitBtnOptionsRef)}>
127   - {() => unref(getSubmitBtnOptionsRef).text}
128   - </Button>
129   - )}
  127 + {getSlot(slots, 'submitBefore')}
  128 + {showSubmitButton && (
  129 + <Button type="primary" {...unref(getSubmitBtnOptionsRef)}>
  130 + {() => unref(getSubmitBtnOptionsRef).text}
  131 + </Button>
  132 + )}
130 133  
131   - {getSlot(slots, 'submitAfter')}
132   - </>
133   - )}
134   - </Form.Item>
135   - )}
136   - </Col>
137   - </>
  134 + {getSlot(slots, 'submitAfter')}
  135 + </>
  136 + )}
  137 + </Form.Item>
  138 + )}
  139 + </Col>
138 140 );
139 141 };
140 142 },
... ...
src/components/Form/src/FormItem.tsx
  1 +import type { ValidationRule } from 'ant-design-vue/types/form/form';
  2 +import type { PropType } from 'vue';
  3 +import type { FormProps } from './types/form';
  4 +import type { FormSchema } from './types/form';
  5 +
1 6 import { defineComponent, computed, unref, toRef } from 'vue';
2 7 import { Form, Col } from 'ant-design-vue';
3 8 import { componentMap } from './componentMap';
  9 +import { BasicHelp } from '/@/components/Basic';
4 10  
5   -import type { PropType } from 'vue';
6   -import type { FormProps } from './types/form';
7   -import type { FormSchema } from './types/form';
8 11 import { isBoolean, isFunction } from '/@/utils/is';
9   -import { useItemLabelWidth } from './hooks/useLabelWidth';
10 12 import { getSlot } from '/@/utils/helper/tsxHelper';
11   -import { BasicHelp } from '/@/components/Basic';
12 13 import { createPlaceholderMessage } from './helper';
13 14 import { upperFirst, cloneDeep } from 'lodash-es';
14   -import { ValidationRule } from 'ant-design-vue/types/form/form';
  15 +
  16 +import { useItemLabelWidth } from './hooks/useLabelWidth';
  17 +
15 18 export default defineComponent({
16 19 name: 'BasicFormItem',
17 20 inheritAttrs: false,
... ... @@ -50,6 +53,7 @@ export default defineComponent({
50 53 schema: schema,
51 54 };
52 55 });
  56 +
53 57 const getShowRef = computed(() => {
54 58 const { show, ifShow, isAdvanced } = props.schema;
55 59 const { showAdvancedButton } = props.formProps;
... ... @@ -226,6 +230,7 @@ export default defineComponent({
226 230 </span>
227 231 );
228 232 }
  233 +
229 234 function renderItem() {
230 235 const { itemProps, slot, render, field } = props.schema;
231 236 const { labelCol, wrapperCol } = unref(itemLabelWidthRef);
... ... @@ -255,11 +260,8 @@ export default defineComponent({
255 260 const { colProps = {}, colSlot, renderColContent, component } = props.schema;
256 261 if (!componentMap.has(component)) return null;
257 262 const { baseColProps = {} } = props.formProps;
258   -
259 263 const realColProps = { ...baseColProps, ...colProps };
260   -
261 264 const { isIfShow, isShow } = unref(getShowRef);
262   -
263 265 const getContent = () => {
264 266 return colSlot
265 267 ? getSlot(slots, colSlot)
... ...
src/components/Form/src/helper.ts
1   -import { ComponentType } from './types/index';
  1 +import type { ComponentType } from './types/index';
  2 +
2 3 /**
3 4 * @description: 生成placeholder
4 5 */
... ... @@ -21,9 +22,11 @@ export function createPlaceholderMessage(component: ComponentType) {
21 22 }
22 23 return '';
23 24 }
  25 +
24 26 function genType() {
25 27 return ['DatePicker', 'MonthPicker', 'RangePicker', 'WeekPicker', 'TimePicker'];
26 28 }
  29 +
27 30 /**
28 31 * 时间字段
29 32 */
... ...
src/components/Form/src/hooks/useAdvanced.ts 0 → 100644
  1 +import type { ColEx } from '../types';
  2 +import type { AdvanceState } from '../types/hooks';
  3 +import type { ComputedRef, Ref } from 'vue';
  4 +import type { FormProps, FormSchema } from '../types/form';
  5 +
  6 +import { computed, unref, watch } from 'vue';
  7 +import { isBoolean, isFunction, isNumber, isObject } from '/@/utils/is';
  8 +
  9 +import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
  10 +
  11 +const BASIC_COL_LEN = 24;
  12 +
  13 +interface UseAdvancedContext {
  14 + advanceState: AdvanceState;
  15 + emit: EmitType;
  16 + getMergePropsRef: ComputedRef<FormProps>;
  17 + getProps: ComputedRef<FormProps>;
  18 + getSchema: ComputedRef<FormSchema[]>;
  19 + formModel: any;
  20 + defaultValueRef: Ref<any>;
  21 +}
  22 +
  23 +export default function ({
  24 + advanceState,
  25 + emit,
  26 + getMergePropsRef,
  27 + getProps,
  28 + getSchema,
  29 + formModel,
  30 + defaultValueRef,
  31 +}: UseAdvancedContext) {
  32 + const { realWidthRef, screenEnum, screenRef } = useBreakpoint();
  33 + const getEmptySpanRef = computed((): number => {
  34 + if (!advanceState.isAdvanced) {
  35 + return 0;
  36 + }
  37 + const emptySpan = unref(getMergePropsRef).emptySpan || 0;
  38 +
  39 + if (isNumber(emptySpan)) {
  40 + return emptySpan;
  41 + }
  42 + if (isObject(emptySpan)) {
  43 + const { span = 0 } = emptySpan;
  44 + const screen = unref(screenRef) as string;
  45 +
  46 + const screenSpan = (emptySpan as any)[screen.toLowerCase()];
  47 + return screenSpan || span || 0;
  48 + }
  49 + return 0;
  50 + });
  51 +
  52 + const getActionPropsRef = computed(() => {
  53 + const {
  54 + resetButtonOptions,
  55 + submitButtonOptions,
  56 + showActionButtonGroup,
  57 + showResetButton,
  58 + showSubmitButton,
  59 + showAdvancedButton,
  60 + actionColOptions,
  61 + } = unref(getProps);
  62 + return {
  63 + resetButtonOptions,
  64 + submitButtonOptions,
  65 + show: showActionButtonGroup,
  66 + showResetButton,
  67 + showSubmitButton,
  68 + showAdvancedButton,
  69 + actionColOptions,
  70 + };
  71 + });
  72 + watch(
  73 + [() => unref(getSchema), () => advanceState.isAdvanced, () => unref(realWidthRef)],
  74 + () => {
  75 + const { showAdvancedButton } = unref(getProps);
  76 + if (showAdvancedButton) {
  77 + updateAdvanced();
  78 + }
  79 + },
  80 + { immediate: true }
  81 + );
  82 +
  83 + function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
  84 + const width = unref(realWidthRef);
  85 +
  86 + const mdWidth =
  87 + parseInt(itemCol.md as string) ||
  88 + parseInt(itemCol.xs as string) ||
  89 + parseInt(itemCol.sm as string) ||
  90 + (itemCol.span as number) ||
  91 + BASIC_COL_LEN;
  92 + const lgWidth = parseInt(itemCol.lg as string) || mdWidth;
  93 + const xlWidth = parseInt(itemCol.xl as string) || lgWidth;
  94 + const xxlWidth = parseInt(itemCol.xxl as string) || xlWidth;
  95 + if (width <= screenEnum.LG) {
  96 + itemColSum += mdWidth;
  97 + } else if (width < screenEnum.XL) {
  98 + itemColSum += lgWidth;
  99 + } else if (width < screenEnum.XXL) {
  100 + itemColSum += xlWidth;
  101 + } else {
  102 + itemColSum += xxlWidth;
  103 + }
  104 + if (isLastAction) {
  105 + advanceState.hideAdvanceBtn = false;
  106 + if (itemColSum <= BASIC_COL_LEN * 2) {
  107 + // 小于等于2行时,不显示收起展开按钮
  108 + advanceState.hideAdvanceBtn = true;
  109 + advanceState.isAdvanced = true;
  110 + } else if (
  111 + itemColSum > BASIC_COL_LEN * 2 &&
  112 + itemColSum <= BASIC_COL_LEN * (unref(getMergePropsRef).autoAdvancedLine || 3)
  113 + ) {
  114 + advanceState.hideAdvanceBtn = false;
  115 +
  116 + // 大于3行默认收起
  117 + } else if (!advanceState.isLoad) {
  118 + advanceState.isLoad = true;
  119 + advanceState.isAdvanced = !advanceState.isAdvanced;
  120 + }
  121 + return { isAdvanced: advanceState.isAdvanced, itemColSum };
  122 + }
  123 + if (itemColSum > BASIC_COL_LEN) {
  124 + return { isAdvanced: advanceState.isAdvanced, itemColSum };
  125 + } else {
  126 + // 第一行始终显示
  127 + return { isAdvanced: true, itemColSum };
  128 + }
  129 + }
  130 +
  131 + function updateAdvanced() {
  132 + let itemColSum = 0;
  133 + let realItemColSum = 0;
  134 + for (const schema of unref(getSchema)) {
  135 + const { show, colProps } = schema;
  136 + let isShow = true;
  137 +
  138 + if (isBoolean(show)) {
  139 + isShow = show;
  140 + }
  141 +
  142 + if (isFunction(show)) {
  143 + isShow = show({
  144 + schema: schema,
  145 + model: formModel,
  146 + field: schema.field,
  147 + values: {
  148 + ...unref(defaultValueRef),
  149 + ...formModel,
  150 + },
  151 + });
  152 + }
  153 +
  154 + if (isShow && colProps) {
  155 + const { itemColSum: sum, isAdvanced } = getAdvanced(colProps, itemColSum);
  156 +
  157 + itemColSum = sum || 0;
  158 + if (isAdvanced) {
  159 + realItemColSum = itemColSum;
  160 + }
  161 + schema.isAdvanced = isAdvanced;
  162 + }
  163 + }
  164 +
  165 + advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpanRef);
  166 +
  167 + getAdvanced(
  168 + unref(getActionPropsRef).actionColOptions || { span: BASIC_COL_LEN },
  169 + itemColSum,
  170 + true
  171 + );
  172 + emit('advanced-change');
  173 + }
  174 +
  175 + function handleToggleAdvanced() {
  176 + advanceState.isAdvanced = !advanceState.isAdvanced;
  177 + }
  178 + return { getActionPropsRef, handleToggleAdvanced };
  179 +}
... ...
src/components/Form/src/hooks/useComponentRegister.ts
  1 +import type { ComponentType } from '../types/index';
1 2 import { tryOnUnmounted } from '/@/utils/helper/vueHelper';
2 3 import { add, del } from '../componentMap';
3   -
4   -import { ComponentType } from '../types/index';
5 4 export function useComponentRegister(compName: ComponentType, comp: any) {
6 5 add(compName, comp);
7 6 tryOnUnmounted(() => {
... ...
src/components/Form/src/hooks/useForm.ts
1 1 import { ref, onUnmounted, unref } from 'vue';
2 2  
3 3 import { isInSetup } from '/@/utils/helper/vueHelper';
  4 +import { isProdMode } from '/@/utils/env';
4 5  
5 6 import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
6   -import { isProdMode } from '/@/utils/env';
7 7 import type { NamePath } from 'ant-design-vue/types/form/form-item';
8 8 import type { ValidateFields } from 'ant-design-vue/types/form/form';
9 9  
... ... @@ -11,6 +11,7 @@ export function useForm(props?: Partial&lt;FormProps&gt;): UseFormReturnType {
11 11 isInSetup();
12 12 const formRef = ref<FormActionType | null>(null);
13 13 const loadedRef = ref<boolean | null>(false);
  14 +
14 15 function getForm() {
15 16 const form = unref(formRef);
16 17 if (!form) {
... ...
src/components/Form/src/hooks/useFormAction.ts 0 → 100644
  1 +import type { ComputedRef, Ref } from 'vue';
  2 +import type { FormProps, FormSchema } from '../types/form';
  3 +import type { Form as FormType } from 'ant-design-vue/types/form/form';
  4 +import type { NamePath } from 'ant-design-vue/types/form/form-item';
  5 +
  6 +import { unref, toRaw } from 'vue';
  7 +
  8 +import { isArray, isFunction, isObject, isString } from '/@/utils/is';
  9 +import { deepMerge, unique } from '/@/utils';
  10 +import { dateItemType } from '../helper';
  11 +import moment from 'moment';
  12 +import { cloneDeep } from 'lodash-es';
  13 +
  14 +interface UseFormActionContext {
  15 + emit: EmitType;
  16 + getProps: ComputedRef<FormProps>;
  17 + getSchema: ComputedRef<FormSchema[]>;
  18 + formModel: any;
  19 + defaultValueRef: Ref<any>;
  20 + formElRef: Ref<FormType>;
  21 + schemaRef: Ref<FormSchema[]>;
  22 + handleFormValues: Fn;
  23 + actionState: {
  24 + resetAction: any;
  25 + submitAction: any;
  26 + };
  27 +}
  28 +export function useFormAction({
  29 + emit,
  30 + getProps,
  31 + formModel,
  32 + getSchema,
  33 + defaultValueRef,
  34 + formElRef,
  35 + schemaRef,
  36 + handleFormValues,
  37 + actionState,
  38 +}: UseFormActionContext) {
  39 + async function resetFields(): Promise<any> {
  40 + const { resetFunc, submitOnReset } = unref(getProps);
  41 + resetFunc && isFunction(resetFunc) && (await resetFunc());
  42 + const formEl = unref(formElRef);
  43 + if (!formEl) return;
  44 + Object.keys(formModel).forEach((key) => {
  45 + (formModel as any)[key] = defaultValueRef.value[key];
  46 + });
  47 + // @ts-ignore
  48 + // TODO 官方组件库类型定义错误,可以不传参数
  49 + formEl.clearValidate();
  50 + emit('reset', toRaw(formModel));
  51 + // return values;
  52 + submitOnReset && handleSubmit();
  53 + }
  54 +
  55 + /**
  56 + * @description: 设置表单值
  57 + */
  58 + async function setFieldsValue(values: any): Promise<void> {
  59 + const fields = unref(getSchema)
  60 + .map((item) => item.field)
  61 + .filter(Boolean);
  62 + const formEl = unref(formElRef);
  63 + Object.keys(values).forEach((key) => {
  64 + const element = values[key];
  65 + if (fields.includes(key) && element !== undefined && element !== null) {
  66 + // 时间
  67 + if (itemIsDateType(key)) {
  68 + if (Array.isArray(element)) {
  69 + const arr: any[] = [];
  70 + for (const ele of element) {
  71 + arr.push(moment(ele));
  72 + }
  73 + (formModel as any)[key] = arr;
  74 + } else {
  75 + (formModel as any)[key] = moment(element);
  76 + }
  77 + } else {
  78 + (formModel as any)[key] = element;
  79 + }
  80 + if (formEl) {
  81 + formEl.validateFields([key]);
  82 + }
  83 + }
  84 + });
  85 + }
  86 + /**
  87 + * @description: 根据字段名删除
  88 + */
  89 + function removeSchemaByFiled(fields: string | string[]): void {
  90 + const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
  91 + if (!fields) {
  92 + return;
  93 + }
  94 + let fieldList: string[] = fields as string[];
  95 + if (isString(fields)) {
  96 + fieldList = [fields];
  97 + }
  98 + for (const field of fieldList) {
  99 + _removeSchemaByFiled(field, schemaList);
  100 + }
  101 + schemaRef.value = schemaList as any;
  102 + }
  103 +
  104 + /**
  105 + * @description: 根据字段名删除
  106 + */
  107 + function _removeSchemaByFiled(field: string, schemaList: FormSchema[]): void {
  108 + if (isString(field)) {
  109 + const index = schemaList.findIndex((schema) => schema.field === field);
  110 + if (index !== -1) {
  111 + schemaList.splice(index, 1);
  112 + }
  113 + }
  114 + }
  115 +
  116 + /**
  117 + * @description: 往某个字段后面插入,如果没有插入最后一个
  118 + */
  119 + function appendSchemaByField(schema: FormSchema, prefixField?: string) {
  120 + const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
  121 +
  122 + const index = schemaList.findIndex((schema) => schema.field === prefixField);
  123 + const hasInList = schemaList.find((item) => item.field === schema.field);
  124 +
  125 + if (hasInList) {
  126 + return;
  127 + }
  128 + if (!prefixField || index === -1) {
  129 + schemaList.push(schema);
  130 + schemaRef.value = schemaList as any;
  131 + return;
  132 + }
  133 + if (index !== -1) {
  134 + schemaList.splice(index + 1, 0, schema);
  135 + }
  136 + schemaRef.value = schemaList as any;
  137 + }
  138 +
  139 + function updateSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
  140 + let updateData: Partial<FormSchema>[] = [];
  141 + if (isObject(data)) {
  142 + updateData.push(data as FormSchema);
  143 + }
  144 + if (isArray(data)) {
  145 + updateData = [...data];
  146 + }
  147 + const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
  148 + if (!hasField) {
  149 + throw new Error('Must pass in the `field` field!');
  150 + }
  151 + const schema: FormSchema[] = [];
  152 + updateData.forEach((item) => {
  153 + unref(getSchema).forEach((val) => {
  154 + if (val.field === item.field) {
  155 + const newScheam = deepMerge(val, item);
  156 + schema.push(newScheam as FormSchema);
  157 + } else {
  158 + schema.push(val);
  159 + }
  160 + });
  161 + });
  162 + schemaRef.value = unique(schema, 'field') as any;
  163 + }
  164 +
  165 + function getFieldsValue(): any {
  166 + const formEl = unref(formElRef);
  167 + if (!formEl) return;
  168 + return handleFormValues(toRaw(unref(formModel)));
  169 + }
  170 +
  171 + /**
  172 + * @description: 是否是时间
  173 + */
  174 + function itemIsDateType(key: string) {
  175 + return unref(getSchema).some((item) => {
  176 + return item.field === key ? dateItemType.includes(item.component!) : false;
  177 + });
  178 + }
  179 +
  180 + function validateFields(nameList?: NamePath[] | undefined) {
  181 + if (!formElRef.value) return;
  182 + return formElRef.value.validateFields(nameList);
  183 + }
  184 +
  185 + function validate(nameList?: NamePath[] | undefined) {
  186 + if (!formElRef.value) return;
  187 + return formElRef.value.validate(nameList);
  188 + }
  189 +
  190 + function clearValidate(name: string | string[]) {
  191 + if (!formElRef.value) return;
  192 + formElRef.value.clearValidate(name);
  193 + }
  194 +
  195 + /**
  196 + * @description: 表单提交
  197 + */
  198 + async function handleSubmit(e?: Event): Promise<void> {
  199 + e && e.preventDefault();
  200 + const { submitFunc } = unref(getProps);
  201 + if (submitFunc && isFunction(submitFunc)) {
  202 + await submitFunc();
  203 + return;
  204 + }
  205 + const formEl = unref(formElRef);
  206 + if (!formEl) return;
  207 + try {
  208 + const values = await formEl.validate();
  209 + const res = handleFormValues(values);
  210 + emit('submit', res);
  211 + } catch (error) {}
  212 + }
  213 + actionState.resetAction = {
  214 + onClick: resetFields,
  215 + };
  216 +
  217 + actionState.submitAction = {
  218 + onClick: handleSubmit,
  219 + };
  220 +
  221 + return {
  222 + handleSubmit,
  223 + clearValidate,
  224 + validate,
  225 + validateFields,
  226 + getFieldsValue,
  227 + updateSchema,
  228 + appendSchemaByField,
  229 + removeSchemaByFiled,
  230 + resetFields,
  231 + setFieldsValue,
  232 + };
  233 +}
... ...
src/components/Form/src/hooks/useFormValues.ts
1 1 import { isArray, isFunction, isObject, isString } from '/@/utils/is';
2 2 import moment from 'moment';
3 3 import { unref } from 'vue';
4   -import type { Ref } from 'vue';
5   -import type { FieldMapToTime } from '../types/form';
  4 +import type { Ref, ComputedRef } from 'vue';
  5 +import type { FieldMapToTime, FormSchema } from '../types/form';
6 6  
7   -export function useFormValues(
8   - transformDateFuncRef: Ref<Fn>,
9   - fieldMapToTimeRef: Ref<FieldMapToTime>
10   -) {
  7 +interface UseFormValuesContext {
  8 + transformDateFuncRef: Ref<Fn>;
  9 + fieldMapToTimeRef: Ref<FieldMapToTime>;
  10 + defaultValueRef: Ref<any>;
  11 + getSchema: ComputedRef<FormSchema[]>;
  12 + formModel: any;
  13 +}
  14 +export function useFormValues({
  15 + transformDateFuncRef,
  16 + fieldMapToTimeRef,
  17 + defaultValueRef,
  18 + getSchema,
  19 + formModel,
  20 +}: UseFormValuesContext) {
11 21 // 处理表单值
12 22 function handleFormValues(values: any) {
13 23 if (!isObject(values)) {
... ... @@ -35,6 +45,7 @@ export function useFormValues(
35 45 }
36 46 return handleRangeTimeValue(resMap);
37 47 }
  48 +
38 49 /**
39 50 * @description: 处理时间区间参数
40 51 */
... ... @@ -58,5 +69,18 @@ export function useFormValues(
58 69  
59 70 return values;
60 71 }
61   - return handleFormValues;
  72 +
  73 + function initDefault() {
  74 + const schemas = unref(getSchema);
  75 + const obj: any = {};
  76 + schemas.forEach((item) => {
  77 + if (item.defaultValue) {
  78 + obj[item.field] = item.defaultValue;
  79 + (formModel as any)[item.field] = item.defaultValue;
  80 + }
  81 + });
  82 + defaultValueRef.value = obj;
  83 + }
  84 +
  85 + return { handleFormValues, initDefault };
62 86 }
... ...
src/components/Form/src/props.ts
... ... @@ -3,6 +3,10 @@ import type { PropType } from &#39;vue&#39;;
3 3 import type { ColEx } from './types';
4 4  
5 5 export const basicProps = {
  6 + model: {
  7 + type: Object as PropType<any>,
  8 + default: {},
  9 + },
6 10 // 标签宽度 固定宽度
7 11 labelWidth: {
8 12 type: [Number, String] as PropType<number | string>,
... ...
src/components/Form/src/types/form.ts
... ... @@ -35,6 +35,8 @@ export type RegisterFn = (formInstance: FormActionType) =&gt; void;
35 35 export type UseFormReturnType = [RegisterFn, FormActionType];
36 36  
37 37 export interface FormProps {
  38 + // 表单值
  39 + model?: any;
38 40 // 整个表单所有项宽度
39 41 labelWidth?: number | string;
40 42 // 重置时提交
... ...
src/components/Form/src/types/hooks.ts 0 → 100644
  1 +export interface AdvanceState {
  2 + isAdvanced: boolean;
  3 + hideAdvanceBtn: boolean;
  4 + isLoad: boolean;
  5 + actionSpan: number;
  6 +}
... ...
src/components/Modal/src/ModalWrapper.tsx
... ... @@ -15,13 +15,12 @@ import {
15 15 import { Spin } from 'ant-design-vue';
16 16  
17 17 import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
18   -// import { useTimeout } from '/@/hooks/core/useTimeout';
  18 +import { useTimeout } from '/@/hooks/core/useTimeout';
19 19  
20 20 import { getSlot } from '/@/utils/helper/tsxHelper';
21 21 import { useElResize } from '/@/hooks/event/useElResize';
22 22 export default defineComponent({
23 23 name: 'ModalWrapper',
24   - emits: ['heightChange', 'getExtHeight'],
25 24 props: {
26 25 loading: {
27 26 type: Boolean as PropType<boolean>,
... ... @@ -52,6 +51,7 @@ export default defineComponent({
52 51 default: false,
53 52 },
54 53 },
  54 + emits: ['heightChange', 'getExtHeight'],
55 55 setup(props: ModalWrapperProps, { slots, emit }) {
56 56 const wrapperRef = ref<HTMLElement | null>(null);
57 57 const spinRef = ref<any>(null);
... ... @@ -66,7 +66,7 @@ export default defineComponent({
66 66 });
67 67  
68 68 // 重试次数
69   - // let tryCount = 0;
  69 + let tryCount = 0;
70 70 let stopElResizeFn: Fn = () => {};
71 71  
72 72 watchEffect(() => {
... ... @@ -123,17 +123,17 @@ export default defineComponent({
123 123 }
124 124 await nextTick();
125 125 const spinEl = unref(spinRef);
126   - // if (!spinEl) {
127   - // useTimeout(() => {
128   - // // retry
129   - // if (tryCount < 3) {
130   - // setModalHeight();
131   - // }
132   - // tryCount++;
133   - // }, 10);
134   - // return;
135   - // }
136   - // tryCount = 0;
  126 + if (!spinEl) {
  127 + useTimeout(() => {
  128 + // retry
  129 + if (tryCount < 3) {
  130 + setModalHeight();
  131 + }
  132 + tryCount++;
  133 + }, 10);
  134 + return;
  135 + }
  136 + tryCount = 0;
137 137  
138 138 const spinContainerEl = spinEl.$el.querySelector('.ant-spin-container') as HTMLElement;
139 139 if (!spinContainerEl) return;
... ... @@ -142,7 +142,7 @@ export default defineComponent({
142 142  
143 143 if (props.fullScreen) {
144 144 realHeightRef.value =
145   - window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight - 26;
  145 + window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight - 6;
146 146 } else {
147 147 realHeightRef.value = realHeight > maxHeight ? maxHeight : realHeight + 16 + 30;
148 148 }
... ...
src/components/Modal/src/useModal.ts
... ... @@ -5,8 +5,9 @@ import type {
5 5 ReturnMethods,
6 6 UseModalInnerReturnType,
7 7 } from './types';
8   -import { ref, onUnmounted, unref, getCurrentInstance, reactive, computed } from 'vue';
  8 +import { ref, onUnmounted, unref, getCurrentInstance, reactive, computed, watchEffect } from 'vue';
9 9 import { isProdMode } from '/@/utils/env';
  10 +import { isFunction } from '/@/utils/is';
10 11 const dataTransferRef = reactive<any>({});
11 12  
12 13 /**
... ... @@ -58,7 +59,7 @@ export function useModal(): UseModalReturnType {
58 59 return [register, methods];
59 60 }
60 61  
61   -export const useModalInner = (): UseModalInnerReturnType => {
  62 +export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => {
62 63 const modalInstanceRef = ref<ModalMethods | null>(null);
63 64 const currentInstall = getCurrentInstance();
64 65 const uidRef = ref<string>('');
... ... @@ -81,6 +82,13 @@ export const useModalInner = (): UseModalInnerReturnType =&gt; {
81 82 currentInstall.emit('register', modalInstance);
82 83 };
83 84  
  85 + watchEffect(() => {
  86 + const data = dataTransferRef[unref(uidRef)];
  87 + if (!data) return;
  88 + if (!callbackFn || !isFunction(callbackFn)) return;
  89 + callbackFn(data);
  90 + });
  91 +
84 92 return [
85 93 register,
86 94 {
... ...
src/views/demo/comp/modal/Modal4.vue
1 1 <template>
2 2 <BasicModal v-bind="$attrs" @register="register" title="Modal Title">
3 3 <p class="h-20">外部传递数据: {{ receiveModalDataRef }}</p>
  4 + <BasicForm @register="registerForm" :model="model" />
4 5 </BasicModal>
5 6 </template>
6 7 <script lang="ts">
7   - import { defineComponent } from 'vue';
  8 + import { defineComponent, nextTick, ref } from 'vue';
8 9 import { BasicModal, useModalInner } from '/@/components/Modal';
  10 + import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  11 + const schemas: FormSchema[] = [
  12 + {
  13 + field: 'field1',
  14 + component: 'Input',
  15 + label: '字段1',
  16 + colProps: {
  17 + span: 12,
  18 + },
  19 + defaultValue: '111',
  20 + },
  21 + {
  22 + field: 'field2',
  23 + component: 'Input',
  24 + label: '字段2',
  25 + colProps: {
  26 + span: 12,
  27 + },
  28 + },
  29 + ];
9 30 export default defineComponent({
10   - components: { BasicModal },
  31 + components: { BasicModal, BasicForm },
11 32 setup() {
12   - const [register, { receiveModalDataRef }] = useModalInner();
13   - return { register, receiveModalDataRef };
  33 + const modelRef = ref({});
  34 + const [
  35 + registerForm,
  36 + {
  37 + // setFieldsValue,
  38 + // setProps
  39 + },
  40 + ] = useForm({
  41 + labelWidth: 120,
  42 + schemas,
  43 + showActionButtonGroup: false,
  44 + actionColOptions: {
  45 + span: 24,
  46 + },
  47 + });
  48 +
  49 + const [register, { receiveModalDataRef }] = useModalInner((data) => {
  50 + nextTick(() => {
  51 + // 方式1
  52 + // setFieldsValue({
  53 + // field2: data.data,
  54 + // field1: data.info,
  55 + // });
  56 +
  57 + // 方式2
  58 + modelRef.value = { field2: data.data, field1: data.info };
  59 +
  60 + // setProps({
  61 + // model:{ field2: data.data, field1: data.info }
  62 + // })
  63 + });
  64 + });
  65 + return { register, receiveModalDataRef, schemas, registerForm, model: modelRef };
14 66 },
15 67 });
16 68 </script>
... ...
src/views/demo/comp/modal/index.vue
... ... @@ -48,6 +48,12 @@
48 48 data: 'content',
49 49 info: 'Info',
50 50 });
  51 + // setTimeout(() => {
  52 + // transferModalData({
  53 + // data: 'content1',
  54 + // info: 'Info1',
  55 + // });
  56 + // }, 3000);
51 57 openModal4(true);
52 58 }
53 59 function openModalLoading() {
... ...