feat: 表单 Schema 支持组件 Props 映射泛型,同步适配VxeGrid

This commit is contained in:
dullathanol
2026-04-04 23:40:27 +08:00
parent 96d6f89732
commit 5211f5065d
29 changed files with 516 additions and 662 deletions

View File

@@ -3,7 +3,6 @@ export { setupVbenForm } from './config';
export type {
BaseFormComponentType,
ExtendedFormApi,
FormActions,
VbenFormProps,
FormSchema as VbenFormSchema,
} from './types';

View File

@@ -221,6 +221,70 @@ type RenderComponentContentType = (
api: FormActions,
) => Record<string, any>;
type MappedComponentProps<P> =
| ((
value: Partial<Record<string, any>>,
actions: FormActions,
) => P & Record<string, any>)
| (P & Record<string, any>);
interface FormSchemaBody extends FormCommonConfig {
/** 默认值 */
defaultValue?: any;
/** 依赖 */
dependencies?: FormItemDependencies;
/** 描述 */
description?: CustomRenderType;
/** 字段名 */
fieldName: string;
/** 帮助信息 */
help?: CustomParamsRenderType;
/** 是否隐藏表单项 */
hide?: boolean;
/** 表单项 */
label?: CustomRenderType;
// 自定义组件内部渲染
renderComponentContent?: RenderComponentContentType;
/** 字段规则 */
rules?: FormSchemaRuleType;
/** 后缀 */
suffix?: CustomRenderType;
}
type FormSchemaDiscriminated<
T extends BaseFormComponentType,
P extends Record<string, any>,
> = {
[K in Extract<keyof P, T>]: {
/** 组件 */
component: K;
/** 组件参数 */
componentProps?: MappedComponentProps<P[K]>;
} & FormSchemaBody;
}[Extract<keyof P, T>];
type FormSchemaFallback<
T extends BaseFormComponentType,
P extends Record<string, any>,
> = {
/** 组件 */
component: Component | Exclude<T, Extract<keyof P, T>>;
/** 组件参数 */
componentProps?: ComponentProps;
} & FormSchemaBody;
export type FormSchema<
T extends BaseFormComponentType = BaseFormComponentType,
P extends Record<string, any> = Record<never, never>,
> = [keyof P] extends [never]
? {
/** 组件 */
component: Component | T;
/** 组件参数 */
componentProps?: ComponentProps;
} & FormSchemaBody
: FormSchemaDiscriminated<T, P> | FormSchemaFallback<T, P>;
export type HandleSubmitFn = (
values: Record<string, any>,
) => Promise<void> | void;
@@ -246,41 +310,13 @@ export type ArrayToStringFields = Array<
| string[] // 简单数组格式,最后一个元素可以是分隔符
>;
export interface FormSchema<
T extends BaseFormComponentType = BaseFormComponentType,
> extends FormCommonConfig {
/** 组件 */
component: Component | T;
/** 组件参数 */
componentProps?: ComponentProps;
/** 默认值 */
defaultValue?: any;
/** 依赖 */
dependencies?: FormItemDependencies;
/** 描述 */
description?: CustomRenderType;
/** 字段名 */
fieldName: string;
/** 帮助信息 */
help?: CustomParamsRenderType;
/** 是否隐藏表单项 */
hide?: boolean;
/** 表单项 */
label?: CustomRenderType;
// 自定义组件内部渲染
renderComponentContent?: RenderComponentContentType;
/** 字段规则 */
rules?: FormSchemaRuleType;
/** 后缀 */
suffix?: CustomRenderType;
}
export interface FormFieldProps extends FormSchema {
required?: boolean;
}
export interface FormRenderProps<
T extends BaseFormComponentType = BaseFormComponentType,
P extends Record<string, any> = Record<never, never>,
> {
/**
* 表单字段数组映射字符串配置 默认使用","
@@ -332,7 +368,7 @@ export interface FormRenderProps<
/**
* 表单定义
*/
schema?: FormSchema<T>[];
schema?: FormSchema<T, P>[];
/**
* 是否显示展开/折叠
@@ -357,8 +393,9 @@ export interface ActionButtonOptions extends VbenButtonProps {
export interface VbenFormProps<
T extends BaseFormComponentType = BaseFormComponentType,
P extends Record<string, any> = Record<never, never>,
> extends Omit<
FormRenderProps<T>,
FormRenderProps<T, P>,
'componentBindEventMap' | 'componentMap' | 'form'
> {
/**

View File

@@ -13,9 +13,10 @@ import VbenUseForm from './vben-use-form.vue';
export function useVbenForm<
T extends BaseFormComponentType = BaseFormComponentType,
>(options: VbenFormProps<T>) {
P extends Record<string, any> = Record<never, never>,
>(options: VbenFormProps<T, P>) {
const IS_REACTIVE = isReactive(options);
const api = new FormApi(options);
const api = new FormApi(options as unknown as VbenFormProps);
const extendedApi: ExtendedFormApi = api as never;
extendedApi.useStore = (selector) => {
return useStore(api.store, selector);