Просмотр исходного кода

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

dullathanol 2 месяцев назад
Родитель
Сommit
064a6a20f0
29 измененных файлов с 516 добавлено и 662 удалено
  1. 58 1
      apps/web-antd/src/adapter/component/index.ts
  2. 0 95
      apps/web-antd/src/adapter/form-schema.ts
  3. 8 11
      apps/web-antd/src/adapter/form.ts
  4. 11 3
      apps/web-antd/src/adapter/vxe-table.ts
  5. 63 2
      apps/web-antdv-next/src/adapter/component/index.ts
  6. 0 95
      apps/web-antdv-next/src/adapter/form-schema.ts
  7. 8 12
      apps/web-antdv-next/src/adapter/form.ts
  8. 11 3
      apps/web-antdv-next/src/adapter/vxe-table.ts
  9. 46 1
      apps/web-ele/src/adapter/component/index.ts
  10. 0 79
      apps/web-ele/src/adapter/form-schema.ts
  11. 8 11
      apps/web-ele/src/adapter/form.ts
  12. 11 3
      apps/web-ele/src/adapter/vxe-table.ts
  13. 43 1
      apps/web-naive/src/adapter/component/index.ts
  14. 0 76
      apps/web-naive/src/adapter/form-schema.ts
  15. 8 11
      apps/web-naive/src/adapter/form.ts
  16. 11 3
      apps/web-naive/src/adapter/vxe-table.ts
  17. 56 1
      apps/web-tdesign/src/adapter/component/index.ts
  18. 0 89
      apps/web-tdesign/src/adapter/form-schema.ts
  19. 8 11
      apps/web-tdesign/src/adapter/form.ts
  20. 11 3
      apps/web-tdesign/src/adapter/vxe-table.ts
  21. 0 1
      packages/@core/ui-kit/form-ui/src/index.ts
  22. 68 31
      packages/@core/ui-kit/form-ui/src/types.ts
  23. 3 2
      packages/@core/ui-kit/form-ui/src/use-vben-form.ts
  24. 6 4
      packages/effects/plugins/src/vxe-table/types.ts
  25. 8 3
      packages/effects/plugins/src/vxe-table/use-vxe-grid.ts
  26. 58 1
      playground/src/adapter/component/index.ts
  27. 0 95
      playground/src/adapter/form-schema.ts
  28. 9 11
      playground/src/adapter/form.ts
  29. 3 3
      playground/src/adapter/vxe-table.ts

+ 58 - 1
apps/web-antd/src/adapter/component/index.ts

@@ -6,14 +6,38 @@
 /* eslint-disable vue/one-component-per-file */
 
 import type {
+  AutoCompleteProps,
+  ButtonProps,
+  CascaderProps,
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DividerProps,
+  InputNumberProps,
+  InputProps,
+  MentionsProps,
+  RadioGroupProps,
+  RadioProps,
+  RateProps,
+  SelectProps,
+  SpaceProps,
+  SwitchProps,
+  TextAreaProps,
+  TimePickerProps,
+  TreeSelectProps,
   UploadChangeParam,
   UploadFile,
   UploadProps,
 } from 'ant-design-vue';
+import type { RangePickerProps } from 'ant-design-vue/es/date-picker';
 
 import type { Component, Ref } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Sortable } from '@vben/hooks';
 import type { Recordable } from '@vben/types';
 
@@ -592,6 +616,39 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiCascader: ApiComponentSharedProps & CascaderProps;
+  ApiSelect: ApiComponentSharedProps & SelectProps;
+  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
+  AutoComplete: AutoCompleteProps;
+  Cascader: CascaderProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  DefaultButton: ButtonProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  InputPassword: InputProps;
+  Mentions: MentionsProps;
+  PrimaryButton: ButtonProps;
+  Radio: RadioProps;
+  RadioGroup: RadioGroupProps;
+  RangePicker: RangePickerProps;
+  Rate: RateProps;
+  Select: SelectProps;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  Textarea: TextAreaProps;
+  TimePicker: TimePickerProps;
+  TreeSelect: TreeSelectProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 95
apps/web-antd/src/adapter/form-schema.ts

@@ -1,95 +0,0 @@
-import type {
-  AutoCompleteProps,
-  ButtonProps,
-  CascaderProps,
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DividerProps,
-  InputNumberProps,
-  InputProps,
-  MentionsProps,
-  RadioGroupProps,
-  RadioProps,
-  RateProps,
-  SelectProps,
-  SpaceProps,
-  SwitchProps,
-  TextAreaProps,
-  TimePickerProps,
-  TreeSelectProps,
-  UploadProps,
-} from 'ant-design-vue';
-import type { RangePickerProps } from 'ant-design-vue/es/date-picker';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiCascader: ApiComponentSharedProps & CascaderProps;
-  ApiSelect: ApiComponentSharedProps & SelectProps;
-  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
-  AutoComplete: AutoCompleteProps;
-  Cascader: CascaderProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  DefaultButton: ButtonProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  InputPassword: InputProps;
-  Mentions: MentionsProps;
-  PrimaryButton: ButtonProps;
-  Radio: RadioProps;
-  RadioGroup: RadioGroupProps;
-  RangePicker: RangePickerProps;
-  Rate: RateProps;
-  Select: SelectProps;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  Textarea: TextAreaProps;
-  TimePicker: TimePickerProps;
-  TreeSelect: TreeSelectProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 8 - 11
apps/web-antd/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -39,14 +41,9 @@ async function initSetupVbenForm() {
   });
 }
 
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
 
-export type { VbenFormProps, VbenFormSchema };
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 11 - 3
apps/web-antd/src/adapter/vxe-table.ts

@@ -1,8 +1,14 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 
+import type { ComponentPropsMap, ComponentType } from './component';
+
 import { h } from 'vue';
 
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
+import { useVbenForm as useForm } from '@vben/common-ui';
+import {
+  setupVbenVxeTable,
+  useVbenVxeGrid as useGrid,
+} from '@vben/plugins/vxe-table';
 
 import { Button, Image } from 'ant-design-vue';
 
@@ -62,9 +68,11 @@ setupVbenVxeTable({
     // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
     // vxeUI.formats.add
   },
-  useVbenForm,
+  useVbenForm: useVbenForm as typeof useForm,
 });
 
-export { useVbenVxeGrid };
+export const useVbenVxeGrid = <T extends Record<string, any>>(
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type * from '@vben/plugins/vxe-table';

+ 63 - 2
apps/web-antdv-next/src/adapter/component/index.ts

@@ -5,11 +5,39 @@
 
 /* eslint-disable vue/one-component-per-file */
 
-import type { UploadChangeParam, UploadFile, UploadProps } from 'antdv-next';
+import type {
+  AutoCompleteProps,
+  ButtonProps,
+  CascaderProps,
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DividerProps,
+  InputNumberProps,
+  InputProps,
+  MentionsProps,
+  RadioGroupProps,
+  RadioProps,
+  RangePickerProps,
+  RateProps,
+  SelectProps,
+  SpaceProps,
+  SwitchProps,
+  TextAreaProps,
+  TimePickerProps,
+  TreeSelectProps,
+  UploadChangeParam,
+  UploadFile,
+  UploadProps,
+} from 'antdv-next';
 
 import type { Component, Ref } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Recordable } from '@vben/types';
 
 import {
@@ -521,6 +549,39 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiCascader: ApiComponentSharedProps & CascaderProps;
+  ApiSelect: ApiComponentSharedProps & SelectProps;
+  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
+  AutoComplete: AutoCompleteProps;
+  Cascader: CascaderProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  DefaultButton: ButtonProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  InputPassword: InputProps;
+  Mentions: MentionsProps;
+  PrimaryButton: ButtonProps;
+  Radio: RadioProps;
+  RadioGroup: RadioGroupProps;
+  RangePicker: RangePickerProps;
+  Rate: RateProps;
+  Select: SelectProps;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  Textarea: TextAreaProps;
+  TimePicker: TimePickerProps;
+  TreeSelect: TreeSelectProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 95
apps/web-antdv-next/src/adapter/form-schema.ts

@@ -1,95 +0,0 @@
-import type {
-  AutoCompleteProps,
-  ButtonProps,
-  CascaderProps,
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DividerProps,
-  InputNumberProps,
-  InputProps,
-  MentionsProps,
-  RadioGroupProps,
-  RadioProps,
-  RangePickerProps,
-  RateProps,
-  SelectProps,
-  SpaceProps,
-  SwitchProps,
-  TextAreaProps,
-  TimePickerProps,
-  TreeSelectProps,
-  UploadProps,
-} from 'antdv-next';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiCascader: ApiComponentSharedProps & CascaderProps;
-  ApiSelect: ApiComponentSharedProps & SelectProps;
-  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
-  AutoComplete: AutoCompleteProps;
-  Cascader: CascaderProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  DefaultButton: ButtonProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  InputPassword: InputProps;
-  Mentions: MentionsProps;
-  PrimaryButton: ButtonProps;
-  Radio: RadioProps;
-  RadioGroup: RadioGroupProps;
-  RangePicker: RangePickerProps;
-  Rate: RateProps;
-  Select: SelectProps;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  Textarea: TextAreaProps;
-  TimePicker: TimePickerProps;
-  TreeSelect: TreeSelectProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 8 - 12
apps/web-antdv-next/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -38,15 +40,9 @@ async function initSetupVbenForm() {
     },
   });
 }
-
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
 
-export type { VbenFormProps, VbenFormSchema };
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 11 - 3
apps/web-antdv-next/src/adapter/vxe-table.ts

@@ -1,8 +1,14 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 
+import type { ComponentPropsMap, ComponentType } from './component';
+
 import { h } from 'vue';
 
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
+import { useVbenForm as useForm } from '@vben/common-ui';
+import {
+  setupVbenVxeTable,
+  useVbenVxeGrid as useGrid,
+} from '@vben/plugins/vxe-table';
 
 import { Button, Image } from 'antdv-next';
 
@@ -62,9 +68,11 @@ setupVbenVxeTable({
     // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
     // vxeUI.formats.add
   },
-  useVbenForm,
+  useVbenForm: useVbenForm as typeof useForm,
 });
 
-export { useVbenVxeGrid };
+export const useVbenVxeGrid = <T extends Record<string, any>>(
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type * from '@vben/plugins/vxe-table';

+ 46 - 1
apps/web-ele/src/adapter/component/index.ts

@@ -3,9 +3,29 @@
  * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
  */
 
+import type {
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DividerProps,
+  ElTimePicker as ElTimePickerType,
+  ElTreeSelect as ElTreeSelectType,
+  InputNumberProps,
+  InputProps,
+  RadioGroupProps,
+  SelectV2Props,
+  SpaceProps,
+  SwitchProps,
+  UploadProps,
+} from 'element-plus';
+
 import type { Component } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Recordable } from '@vben/types';
 
 import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
@@ -15,6 +35,9 @@ import { $t } from '@vben/locales';
 
 import { ElNotification } from 'element-plus';
 
+type ElTreeSelectSchemaProps = InstanceType<typeof ElTreeSelectType>['$props'];
+type ElTimePickerSchemaProps = InstanceType<typeof ElTimePickerType>['$props'];
+
 const ElButton = defineAsyncComponent(() =>
   Promise.all([
     import('element-plus/es/components/button/index'),
@@ -172,6 +195,28 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiSelect: ApiComponentSharedProps & SelectV2Props;
+  ApiTreeSelect: ApiComponentSharedProps & ElTreeSelectSchemaProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  RadioGroup: RadioGroupProps;
+  Select: SelectV2Props;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  TimePicker: ElTimePickerSchemaProps;
+  TreeSelect: ElTreeSelectSchemaProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 79
apps/web-ele/src/adapter/form-schema.ts

@@ -1,79 +0,0 @@
-import type {
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DividerProps,
-  ElTimePicker,
-  ElTreeSelect,
-  InputNumberProps,
-  InputProps,
-  RadioGroupProps,
-  SelectV2Props,
-  SpaceProps,
-  SwitchProps,
-  UploadProps,
-} from 'element-plus';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ElTreeSelectSchemaProps = InstanceType<typeof ElTreeSelect>['$props'];
-type ElTimePickerSchemaProps = InstanceType<typeof ElTimePicker>['$props'];
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiSelect: ApiComponentSharedProps & SelectV2Props;
-  ApiTreeSelect: ApiComponentSharedProps & ElTreeSelectSchemaProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  RadioGroup: RadioGroupProps;
-  Select: SelectV2Props;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  TimePicker: ElTimePickerSchemaProps;
-  TreeSelect: ElTreeSelectSchemaProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 8 - 11
apps/web-ele/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -31,14 +33,9 @@ async function initSetupVbenForm() {
   });
 }
 
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
 
-export type { VbenFormProps, VbenFormSchema };
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 11 - 3
apps/web-ele/src/adapter/vxe-table.ts

@@ -1,8 +1,14 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 
+import type { ComponentPropsMap, ComponentType } from './component';
+
 import { h } from 'vue';
 
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
+import { useVbenForm as useForm } from '@vben/common-ui';
+import {
+  setupVbenVxeTable,
+  useVbenVxeGrid as useGrid,
+} from '@vben/plugins/vxe-table';
 
 import { ElButton, ElImage } from 'element-plus';
 
@@ -63,9 +69,11 @@ setupVbenVxeTable({
     // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
     // vxeUI.formats.add
   },
-  useVbenForm,
+  useVbenForm: useVbenForm as typeof useForm,
 });
 
-export { useVbenVxeGrid };
+export const useVbenVxeGrid = <T extends Record<string, any>>(
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type * from '@vben/plugins/vxe-table';

+ 43 - 1
apps/web-naive/src/adapter/component/index.ts

@@ -3,9 +3,29 @@
  * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
  */
 
+import type {
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DividerProps,
+  InputNumberProps,
+  InputProps,
+  RadioGroupProps,
+  SelectProps,
+  SpaceProps,
+  SwitchProps,
+  TimePickerProps,
+  TreeSelectProps,
+  UploadProps,
+} from 'naive-ui';
+
 import type { Component } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Recordable } from '@vben/types';
 
 import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
@@ -118,6 +138,28 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiSelect: ApiComponentSharedProps & SelectProps;
+  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  RadioGroup: RadioGroupProps;
+  Select: SelectProps;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  TimePicker: TimePickerProps;
+  TreeSelect: TreeSelectProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 76
apps/web-naive/src/adapter/form-schema.ts

@@ -1,76 +0,0 @@
-import type {
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DividerProps,
-  InputNumberProps,
-  InputProps,
-  RadioGroupProps,
-  SelectProps,
-  SpaceProps,
-  SwitchProps,
-  TimePickerProps,
-  TreeSelectProps,
-  UploadProps,
-} from 'naive-ui';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiSelect: ApiComponentSharedProps & SelectProps;
-  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  RadioGroup: RadioGroupProps;
-  Select: SelectProps;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  TimePicker: TimePickerProps;
-  TreeSelect: TreeSelectProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 8 - 11
apps/web-naive/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -35,14 +37,9 @@ async function initSetupVbenForm() {
   });
 }
 
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
 
-export type { VbenFormProps, VbenFormSchema };
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 11 - 3
apps/web-naive/src/adapter/vxe-table.ts

@@ -1,8 +1,14 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 
+import type { ComponentPropsMap, ComponentType } from './component';
+
 import { h } from 'vue';
 
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
+import { useVbenForm as useForm } from '@vben/common-ui';
+import {
+  setupVbenVxeTable,
+  useVbenVxeGrid as useGrid,
+} from '@vben/plugins/vxe-table';
 
 import { NButton, NImage } from 'naive-ui';
 
@@ -62,9 +68,11 @@ setupVbenVxeTable({
     // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
     // vxeUI.formats.add
   },
-  useVbenForm,
+  useVbenForm: useVbenForm as typeof useForm,
 });
 
-export { useVbenVxeGrid };
+export const useVbenVxeGrid = <T extends Record<string, any>>(
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type * from '@vben/plugins/vxe-table';

+ 56 - 1
apps/web-tdesign/src/adapter/component/index.ts

@@ -1,6 +1,32 @@
+import type {
+  AutoCompleteProps,
+  ButtonProps,
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DateRangePickerProps,
+  DividerProps,
+  InputNumberProps,
+  InputProps,
+  RadioGroupProps,
+  RadioProps,
+  SelectProps,
+  SpaceProps,
+  SwitchProps,
+  TextareaProps,
+  TimePickerProps,
+  TreeSelectProps,
+} from 'tdesign-vue-next';
+import type { TdRateProps } from 'tdesign-vue-next/es/rate/type';
+import type { UploadProps } from 'tdesign-vue-next/es/upload/types';
+
 import type { Component } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Recordable } from '@vben/types';
 
 import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
@@ -126,6 +152,35 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiSelect: ApiComponentSharedProps & SelectProps;
+  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
+  AutoComplete: AutoCompleteProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  DefaultButton: ButtonProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  PrimaryButton: ButtonProps;
+  Radio: RadioProps;
+  RadioGroup: RadioGroupProps;
+  RangePicker: DateRangePickerProps;
+  Rate: TdRateProps;
+  Select: SelectProps;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  Textarea: TextareaProps;
+  TimePicker: TimePickerProps;
+  TreeSelect: TreeSelectProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 89
apps/web-tdesign/src/adapter/form-schema.ts

@@ -1,89 +0,0 @@
-import type {
-  AutoCompleteProps,
-  ButtonProps,
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DateRangePickerProps,
-  DividerProps,
-  InputNumberProps,
-  InputProps,
-  RadioGroupProps,
-  RadioProps,
-  SelectProps,
-  SpaceProps,
-  SwitchProps,
-  TextareaProps,
-  TimePickerProps,
-  TreeSelectProps,
-} from 'tdesign-vue-next';
-import type { TdRateProps } from 'tdesign-vue-next/es/rate/type';
-import type { UploadProps } from 'tdesign-vue-next/es/upload/types';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiSelect: ApiComponentSharedProps & SelectProps;
-  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
-  AutoComplete: AutoCompleteProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  DefaultButton: ButtonProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  PrimaryButton: ButtonProps;
-  Radio: RadioProps;
-  RadioGroup: RadioGroupProps;
-  RangePicker: DateRangePickerProps;
-  Rate: TdRateProps;
-  Select: SelectProps;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  Textarea: TextareaProps;
-  TimePicker: TimePickerProps;
-  TreeSelect: TreeSelectProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 8 - 11
apps/web-tdesign/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -39,14 +41,9 @@ async function initSetupVbenForm() {
   });
 }
 
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
 
-export type { VbenFormProps, VbenFormSchema };
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 11 - 3
apps/web-tdesign/src/adapter/vxe-table.ts

@@ -1,8 +1,14 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 
+import type { ComponentPropsMap, ComponentType } from './component';
+
 import { h } from 'vue';
 
-import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
+import { useVbenForm as useForm } from '@vben/common-ui';
+import {
+  setupVbenVxeTable,
+  useVbenVxeGrid as useGrid,
+} from '@vben/plugins/vxe-table';
 
 import { Button, Image } from 'tdesign-vue-next';
 
@@ -62,9 +68,11 @@ setupVbenVxeTable({
     // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
     // vxeUI.formats.add
   },
-  useVbenForm,
+  useVbenForm: useVbenForm as typeof useForm,
 });
 
-export { useVbenVxeGrid };
+export const useVbenVxeGrid = <T extends Record<string, any>>(
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type * from '@vben/plugins/vxe-table';

+ 0 - 1
packages/@core/ui-kit/form-ui/src/index.ts

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

+ 68 - 31
packages/@core/ui-kit/form-ui/src/types.ts

@@ -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'
 > {
   /**

+ 3 - 2
packages/@core/ui-kit/form-ui/src/use-vben-form.ts

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

+ 6 - 4
packages/effects/plugins/src/vxe-table/types.ts

@@ -41,6 +41,7 @@ export interface SeparatorOptions {
 export interface VxeGridProps<
   T extends Record<string, any> = any,
   D extends BaseFormComponentType = BaseFormComponentType,
+  P extends Record<string, any> = Record<never, never>,
 > {
   /**
    * 数据
@@ -73,7 +74,7 @@ export interface VxeGridProps<
   /**
    * 表单配置
    */
-  formOptions?: VbenFormProps<D>;
+  formOptions?: VbenFormProps<D, P>;
   /**
    * 显示搜索表单
    */
@@ -87,10 +88,11 @@ export interface VxeGridProps<
 export type ExtendedVxeGridApi<
   D extends Record<string, any> = any,
   F extends BaseFormComponentType = BaseFormComponentType,
+  P extends Record<string, any> = Record<never, never>,
 > = VxeGridApi<D> & {
-  useStore: <T = NoInfer<VxeGridProps<D, F>>>(
-    selector?: (state: NoInfer<VxeGridProps<any, any>>) => T,
-  ) => Readonly<Ref<T>>;
+  useStore: <S = NoInfer<VxeGridProps<D, F, P>>>(
+    selector?: (state: NoInfer<VxeGridProps<any, any, any>>) => S,
+  ) => Readonly<Ref<S>>;
 };
 
 export interface SetupVxeTable {

+ 8 - 3
packages/effects/plugins/src/vxe-table/use-vxe-grid.ts

@@ -22,10 +22,15 @@ type FilteredSlots<T> = {
 export function useVbenVxeGrid<
   T extends Record<string, any> = any,
   D extends BaseFormComponentType = BaseFormComponentType,
->(options: VxeGridProps<T, D>) {
+  P extends Record<string, any> = Record<never, never>,
+>(options: VxeGridProps<T, D, P>) {
   // const IS_REACTIVE = isReactive(options);
-  const api = new VxeGridApi(options);
-  const extendedApi: ExtendedVxeGridApi<T, D> = api as ExtendedVxeGridApi<T, D>;
+  const api = new VxeGridApi(options as VxeGridProps);
+  const extendedApi: ExtendedVxeGridApi<T, D, P> = api as ExtendedVxeGridApi<
+    T,
+    D,
+    P
+  >;
   extendedApi.useStore = (selector) => {
     return useStore(api.store, selector);
   };

+ 58 - 1
playground/src/adapter/component/index.ts

@@ -6,14 +6,38 @@
 /* eslint-disable vue/one-component-per-file */
 
 import type {
+  AutoCompleteProps,
+  ButtonProps,
+  CascaderProps,
+  CheckboxGroupProps,
+  CheckboxProps,
+  DatePickerProps,
+  DividerProps,
+  InputNumberProps,
+  InputProps,
+  MentionsProps,
+  RadioGroupProps,
+  RadioProps,
+  RateProps,
+  SelectProps,
+  SpaceProps,
+  SwitchProps,
+  TextAreaProps,
+  TimePickerProps,
+  TreeSelectProps,
   UploadChangeParam,
   UploadFile,
   UploadProps,
 } from 'ant-design-vue';
+import type { RangePickerProps } from 'ant-design-vue/es/date-picker';
 
 import type { Component, Ref } from 'vue';
 
-import type { BaseFormComponentType } from '@vben/common-ui';
+import type {
+  ApiComponentSharedProps,
+  BaseFormComponentType,
+  IconPickerProps,
+} from '@vben/common-ui';
 import type { Sortable } from '@vben/hooks';
 import type { Recordable } from '@vben/types';
 
@@ -594,6 +618,39 @@ export type ComponentType =
   | 'Upload'
   | BaseFormComponentType;
 
+/**
+ * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
+ */
+export interface ComponentPropsMap {
+  ApiCascader: ApiComponentSharedProps & CascaderProps;
+  ApiSelect: ApiComponentSharedProps & SelectProps;
+  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
+  AutoComplete: AutoCompleteProps;
+  Cascader: CascaderProps;
+  Checkbox: CheckboxProps;
+  CheckboxGroup: CheckboxGroupProps;
+  DatePicker: DatePickerProps;
+  DefaultButton: ButtonProps;
+  Divider: DividerProps;
+  IconPicker: IconPickerProps;
+  Input: InputProps;
+  InputNumber: InputNumberProps;
+  InputPassword: InputProps;
+  Mentions: MentionsProps;
+  PrimaryButton: ButtonProps;
+  Radio: RadioProps;
+  RadioGroup: RadioGroupProps;
+  RangePicker: RangePickerProps;
+  Rate: RateProps;
+  Select: SelectProps;
+  Space: SpaceProps;
+  Switch: SwitchProps;
+  Textarea: TextAreaProps;
+  TimePicker: TimePickerProps;
+  TreeSelect: TreeSelectProps;
+  Upload: UploadProps;
+}
+
 async function initComponentAdapter() {
   const components: Partial<Record<ComponentType, Component>> = {
     // 如果你的组件体积比较大,可以使用异步加载

+ 0 - 95
playground/src/adapter/form-schema.ts

@@ -1,95 +0,0 @@
-import type {
-  AutoCompleteProps,
-  ButtonProps,
-  CascaderProps,
-  CheckboxGroupProps,
-  CheckboxProps,
-  DatePickerProps,
-  DividerProps,
-  InputNumberProps,
-  InputProps,
-  MentionsProps,
-  RadioGroupProps,
-  RadioProps,
-  RateProps,
-  SelectProps,
-  SpaceProps,
-  SwitchProps,
-  TextAreaProps,
-  TimePickerProps,
-  TreeSelectProps,
-  UploadProps,
-} from 'ant-design-vue';
-import type { RangePickerProps } from 'ant-design-vue/es/date-picker';
-
-import type { Component } from 'vue';
-
-import type {
-  ApiComponentSharedProps,
-  VbenFormSchema as CoreFormSchema,
-  FormActions,
-  IconPickerProps,
-} from '@vben/common-ui';
-
-import type { ComponentType } from './component';
-
-type ComponentProps<P> =
-  | ((
-      value: Partial<Record<string, any>>,
-      actions: FormActions,
-    ) => P & Record<string, any>)
-  | (P & Record<string, any>);
-
-/**
- * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示
- */
-interface ComponentPropsMap {
-  ApiCascader: ApiComponentSharedProps & CascaderProps;
-  ApiSelect: ApiComponentSharedProps & SelectProps;
-  ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps;
-  AutoComplete: AutoCompleteProps;
-  Cascader: CascaderProps;
-  Checkbox: CheckboxProps;
-  CheckboxGroup: CheckboxGroupProps;
-  DatePicker: DatePickerProps;
-  DefaultButton: ButtonProps;
-  Divider: DividerProps;
-  IconPicker: IconPickerProps;
-  Input: InputProps;
-  InputNumber: InputNumberProps;
-  InputPassword: InputProps;
-  Mentions: MentionsProps;
-  PrimaryButton: ButtonProps;
-  Radio: RadioProps;
-  RadioGroup: RadioGroupProps;
-  RangePicker: RangePickerProps;
-  Rate: RateProps;
-  Select: SelectProps;
-  Space: SpaceProps;
-  Switch: SwitchProps;
-  Textarea: TextAreaProps;
-  TimePicker: TimePickerProps;
-  TreeSelect: TreeSelectProps;
-  Upload: UploadProps;
-}
-
-type BaseSchema = Omit<
-  CoreFormSchema<ComponentType>,
-  'component' | 'componentProps'
->;
-
-type RegisteredName = keyof ComponentPropsMap;
-
-type DiscriminatedFormSchema = {
-  [K in RegisteredName]: BaseSchema & {
-    component: K;
-    componentProps?: ComponentProps<ComponentPropsMap[K]>;
-  };
-}[RegisteredName];
-
-type FallbackFormSchema = BaseSchema & {
-  component: Component | Exclude<ComponentType, RegisteredName>;
-  componentProps?: CoreFormSchema<ComponentType>['componentProps'];
-};
-
-export type VbenFormSchema = DiscriminatedFormSchema | FallbackFormSchema;

+ 9 - 11
playground/src/adapter/form.ts

@@ -1,7 +1,9 @@
-import type { VbenFormProps as CoreFormProps } from '@vben/common-ui';
+import type {
+  VbenFormProps as FormProps,
+  VbenFormSchema as FormSchema,
+} from '@vben/common-ui';
 
-import type { ComponentType } from './component';
-import type { VbenFormSchema } from './form-schema';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
@@ -38,13 +40,9 @@ async function initSetupVbenForm() {
   });
 }
 
-type VbenFormProps = Omit<CoreFormProps<ComponentType>, 'schema'> & {
-  schema?: VbenFormSchema[];
-};
-
-function useVbenForm(options: VbenFormProps) {
-  return useForm<ComponentType>(options as CoreFormProps<ComponentType>);
-}
+const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
 
 export { initSetupVbenForm, useVbenForm, z };
-export type { VbenFormProps, VbenFormSchema };
+
+export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
+export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

+ 3 - 3
playground/src/adapter/vxe-table.ts

@@ -1,7 +1,7 @@
 import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 import type { Recordable } from '@vben/types';
 
-import type { ComponentType } from './component';
+import type { ComponentPropsMap, ComponentType } from './component';
 
 import { h } from 'vue';
 
@@ -282,8 +282,8 @@ setupVbenVxeTable({
 });
 
 export const useVbenVxeGrid = <T extends Record<string, any>>(
-  ...rest: Parameters<typeof useGrid<T, ComponentType>>
-) => useGrid<T, ComponentType>(...rest);
+  ...rest: Parameters<typeof useGrid<T, ComponentType, ComponentPropsMap>>
+) => useGrid<T, ComponentType, ComponentPropsMap>(...rest);
 
 export type OnActionClickParams<T = Recordable<any>> = {
   code: string;