From 573637222d9167ef50bf4eb4fb7d8ffe4b983ea3 Mon Sep 17 00:00:00 2001 From: panda7 Date: Wed, 12 Nov 2025 02:03:12 +0800 Subject: [PATCH] feat: add form handleCollapsedChange event (#6893) * feat: add form handleCollapsedChange event * fix: ts lint * fix: ts error --------- Co-authored-by: sqchen --- docs/src/components/common-ui/vben-form.md | 1 + .../form-ui/src/components/form-actions.vue | 4 ++-- packages/@core/ui-kit/form-ui/src/form-api.ts | 1 + packages/@core/ui-kit/form-ui/src/types.ts | 4 ++++ .../ui-kit/form-ui/src/use-form-context.ts | 2 +- .../@core/ui-kit/form-ui/src/vben-form.vue | 4 +++- .../ui-kit/form-ui/src/vben-use-form.vue | 21 +++++++++++-------- 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md index 48772bfa..30cbec44 100644 --- a/docs/src/components/common-ui/vben-form.md +++ b/docs/src/components/common-ui/vben-form.md @@ -335,6 +335,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单 | handleReset | 表单重置回调 | `(values: Record,) => Promise \| void` | - | | handleSubmit | 表单提交回调 | `(values: Record,) => Promise \| void` | - | | handleValuesChange | 表单值变化回调 | `(values: Record, fieldsChanged: string[]) => void` | - | +| handleCollapsedChange | 表单收起展开状态变化回调 | `(collapsed: boolean) => void` | - | | actionButtonsReverse | 调换操作按钮位置 | `boolean` | `false` | | resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - | | submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - | diff --git a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue index 42101c12..36b1caa0 100644 --- a/packages/@core/ui-kit/form-ui/src/components/form-actions.vue +++ b/packages/@core/ui-kit/form-ui/src/components/form-actions.vue @@ -47,7 +47,7 @@ async function handleSubmit(e: Event) { return; } - const values = toRaw(await props.formApi.getValues()); + const values = toRaw(await props.formApi.getValues()) ?? {}; await props.handleSubmit?.(values); } @@ -56,7 +56,7 @@ async function handleReset(e: Event) { e?.stopPropagation(); const props = unref(rootProps); - const values = toRaw(await props.formApi?.getValues()); + const values = toRaw(await props.formApi?.getValues()) ?? {}; if (isFunction(props.handleReset)) { await props.handleReset?.(values); diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts index 401748c3..f5f353dc 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -36,6 +36,7 @@ function getDefaultState(): VbenFormProps { handleReset: undefined, handleSubmit: undefined, handleValuesChange: undefined, + handleCollapsedChange: undefined, layout: 'horizontal', resetButtonOptions: {}, schema: [], diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts index 824b7a44..6d704145 100644 --- a/packages/@core/ui-kit/form-ui/src/types.ts +++ b/packages/@core/ui-kit/form-ui/src/types.ts @@ -379,6 +379,10 @@ export interface VbenFormProps< * 表单字段映射 */ fieldMappingTime?: FieldMappingTime; + /** + * 表单收起展开状态变化回调 + */ + handleCollapsedChange?: (collapsed: boolean) => void; /** * 表单重置回调 */ diff --git a/packages/@core/ui-kit/form-ui/src/use-form-context.ts b/packages/@core/ui-kit/form-ui/src/use-form-context.ts index 4ef182ed..e95c87b9 100644 --- a/packages/@core/ui-kit/form-ui/src/use-form-context.ts +++ b/packages/@core/ui-kit/form-ui/src/use-form-context.ts @@ -13,7 +13,7 @@ import { useForm } from 'vee-validate'; import { object, ZodIntersection, ZodNumber, ZodObject, ZodString } from 'zod'; import { getDefaultsForSchema } from 'zod-defaults'; -type ExtendFormProps = VbenFormProps & { formApi: ExtendedFormApi }; +type ExtendFormProps = VbenFormProps & { formApi?: ExtendedFormApi }; export const [injectFormProps, provideFormProps] = createContext<[ComputedRef | ExtendFormProps, FormActions]>( diff --git a/packages/@core/ui-kit/form-ui/src/vben-form.vue b/packages/@core/ui-kit/form-ui/src/vben-form.vue index 260e75cd..f3ba37f0 100644 --- a/packages/@core/ui-kit/form-ui/src/vben-form.vue +++ b/packages/@core/ui-kit/form-ui/src/vben-form.vue @@ -40,7 +40,9 @@ const { delegatedSlots, form } = useFormInitial(props); provideFormProps([props, form]); const handleUpdateCollapsed = (value: boolean) => { - currentCollapsed.value = !!value; + currentCollapsed.value = value; + // 触发收起展开状态变化回调 + props.handleCollapsedChange?.(value); }; watchEffect(() => { diff --git a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue index 3e7b00b6..e9386725 100644 --- a/packages/@core/ui-kit/form-ui/src/vben-use-form.vue +++ b/packages/@core/ui-kit/form-ui/src/vben-use-form.vue @@ -25,7 +25,7 @@ import { } from './use-form-context'; // 通过 extends 会导致热更新卡死,所以重复写了一遍 interface Props extends VbenFormProps { - formApi: ExtendedFormApi; + formApi?: ExtendedFormApi; } const props = defineProps(); @@ -44,11 +44,13 @@ provideComponentRefMap(componentRefMap); props.formApi?.mount?.(form, componentRefMap); const handleUpdateCollapsed = (value: boolean) => { - props.formApi?.setState({ collapsed: !!value }); + props.formApi?.setState({ collapsed: value }); + // 触发收起展开状态变化回调 + forward.value.handleCollapsedChange?.(value); }; function handleKeyDownEnter(event: KeyboardEvent) { - if (!state.value.submitOnEnter || !forward.value.formApi?.isMounted) { + if (!state?.value.submitOnEnter || !forward.value.formApi?.isMounted) { return; } // 如果是 textarea 不阻止默认行为,否则会导致无法换行。 @@ -58,11 +60,11 @@ function handleKeyDownEnter(event: KeyboardEvent) { } event.preventDefault(); - forward.value.formApi.validateAndSubmitForm(); + forward.value.formApi?.validateAndSubmitForm(); } const handleValuesChangeDebounced = useDebounceFn(async () => { - state.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm(); + state?.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm(); }, 300); const valuesCache: Recordable = {}; @@ -74,7 +76,7 @@ onMounted(async () => { () => form.values, async (newVal) => { if (forward.value.handleValuesChange) { - const fields = state.value.schema?.map((item) => { + const fields = state?.value.schema?.map((item) => { return item.fieldName; }); @@ -91,8 +93,9 @@ onMounted(async () => { if (changedFields.length > 0) { // 调用handleValuesChange回调,传入所有表单值的深拷贝和变更的字段列表 + const values = await forward.value.formApi?.getValues(); forward.value.handleValuesChange( - cloneDeep(await forward.value.formApi.getValues()), + cloneDeep(values ?? {}) as Record, changedFields, ); } @@ -109,7 +112,7 @@ onMounted(async () => {
{