feat: add form handleCollapsedChange event (#6893)

* feat: add form handleCollapsedChange event

* fix: ts lint

* fix: ts error

---------

Co-authored-by: sqchen <chenshiqi@sshlx.com>
This commit is contained in:
panda7 2025-11-12 02:03:12 +08:00 committed by GitHub
parent a4aa133db5
commit 573637222d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 24 additions and 13 deletions

View File

@ -335,6 +335,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
| handleReset | 表单重置回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
| handleSubmit | 表单提交回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
| handleValuesChange | 表单值变化回调 | `(values: Record<string, any>, fieldsChanged: string[]) => void` | - |
| handleCollapsedChange | 表单收起展开状态变化回调 | `(collapsed: boolean) => void` | - |
| actionButtonsReverse | 调换操作按钮位置 | `boolean` | `false` |
| resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - |
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |

View File

@ -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);

View File

@ -36,6 +36,7 @@ function getDefaultState(): VbenFormProps {
handleReset: undefined,
handleSubmit: undefined,
handleValuesChange: undefined,
handleCollapsedChange: undefined,
layout: 'horizontal',
resetButtonOptions: {},
schema: [],

View File

@ -379,6 +379,10 @@ export interface VbenFormProps<
*
*/
fieldMappingTime?: FieldMappingTime;
/**
*
*/
handleCollapsedChange?: (collapsed: boolean) => void;
/**
*
*/

View File

@ -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> | ExtendFormProps, FormActions]>(

View File

@ -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(() => {

View File

@ -25,7 +25,7 @@ import {
} from './use-form-context';
// extends
interface Props extends VbenFormProps {
formApi: ExtendedFormApi;
formApi?: ExtendedFormApi;
}
const props = defineProps<Props>();
@ -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<any> = {};
@ -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<string, any>,
changedFields,
);
}
@ -109,7 +112,7 @@ onMounted(async () => {
<Form
@keydown.enter="handleKeyDownEnter"
v-bind="forward"
:collapsed="state.collapsed"
:collapsed="state?.collapsed"
:component-bind-event-map="COMPONENT_BIND_EVENT_MAP"
:component-map="COMPONENT_MAP"
:form="form"
@ -126,7 +129,7 @@ onMounted(async () => {
<slot v-bind="slotProps">
<FormActions
v-if="forward.showDefaultActions"
:model-value="state.collapsed"
:model-value="state?.collapsed"
@update:model-value="handleUpdateCollapsed"
>
<template #reset-before="resetSlotProps">