fix: 补全 ComponentPropsMap 与 Vxe 表格表单链路的类型

This commit is contained in:
dullathanol
2026-04-05 19:03:03 +08:00
committed by allen
parent e417a2c209
commit 2013ba4de4
13 changed files with 72 additions and 31 deletions

View File

@@ -68,6 +68,16 @@ import { isEmpty } from '@vben/utils';
import { message, Modal, notification } from 'ant-design-vue'; import { message, Modal, notification } from 'ant-design-vue';
type AdapterUploadProps = UploadProps & {
aspectRatio?: string;
crop?: boolean;
draggable?: boolean;
handleChange?: (event: UploadChangeParam) => void;
maxSize?: number;
onDragSort?: (oldIndex: number, newIndex: number) => void;
onHandleChange?: (event: UploadChangeParam) => void;
};
const AutoComplete = defineAsyncComponent( const AutoComplete = defineAsyncComponent(
() => import('ant-design-vue/es/auto-complete'), () => import('ant-design-vue/es/auto-complete'),
); );
@@ -646,7 +656,7 @@ export interface ComponentPropsMap {
Textarea: TextAreaProps; Textarea: TextAreaProps;
TimePicker: TimePickerProps; TimePicker: TimePickerProps;
TreeSelect: TreeSelectProps; TreeSelect: TreeSelectProps;
Upload: UploadProps; Upload: AdapterUploadProps;
} }
async function initComponentAdapter() { async function initComponentAdapter() {

View File

@@ -4,7 +4,6 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { h } from 'vue'; import { h } from 'vue';
import { useVbenForm as useForm } from '@vben/common-ui';
import { import {
setupVbenVxeTable, setupVbenVxeTable,
useVbenVxeGrid as useGrid, useVbenVxeGrid as useGrid,
@@ -68,7 +67,7 @@ setupVbenVxeTable({
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add // vxeUI.formats.add
}, },
useVbenForm: useVbenForm as typeof useForm, useVbenForm,
}); });
export const useVbenVxeGrid = <T extends Record<string, any>>( export const useVbenVxeGrid = <T extends Record<string, any>>(

View File

@@ -63,6 +63,14 @@ import { isEmpty } from '@vben/utils';
import { message, Modal, notification } from 'antdv-next'; import { message, Modal, notification } from 'antdv-next';
type AdapterUploadProps = UploadProps & {
aspectRatio?: string;
crop?: boolean;
handleChange?: (event: UploadChangeParam) => void;
maxSize?: number;
onHandleChange?: (event: UploadChangeParam) => void;
};
const AutoComplete = defineAsyncComponent( const AutoComplete = defineAsyncComponent(
() => import('antdv-next/dist/auto-complete/index'), () => import('antdv-next/dist/auto-complete/index'),
); );
@@ -579,7 +587,7 @@ export interface ComponentPropsMap {
Textarea: TextAreaProps; Textarea: TextAreaProps;
TimePicker: TimePickerProps; TimePicker: TimePickerProps;
TreeSelect: TreeSelectProps; TreeSelect: TreeSelectProps;
Upload: UploadProps; Upload: AdapterUploadProps;
} }
async function initComponentAdapter() { async function initComponentAdapter() {

View File

@@ -4,7 +4,6 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { h } from 'vue'; import { h } from 'vue';
import { useVbenForm as useForm } from '@vben/common-ui';
import { import {
setupVbenVxeTable, setupVbenVxeTable,
useVbenVxeGrid as useGrid, useVbenVxeGrid as useGrid,
@@ -68,7 +67,7 @@ setupVbenVxeTable({
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add // vxeUI.formats.add
}, },
useVbenForm: useVbenForm as typeof useForm, useVbenForm,
}); });
export const useVbenVxeGrid = <T extends Record<string, any>>( export const useVbenVxeGrid = <T extends Record<string, any>>(

View File

@@ -4,7 +4,6 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { h } from 'vue'; import { h } from 'vue';
import { useVbenForm as useForm } from '@vben/common-ui';
import { import {
setupVbenVxeTable, setupVbenVxeTable,
useVbenVxeGrid as useGrid, useVbenVxeGrid as useGrid,
@@ -69,7 +68,7 @@ setupVbenVxeTable({
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add // vxeUI.formats.add
}, },
useVbenForm: useVbenForm as typeof useForm, useVbenForm,
}); });
export const useVbenVxeGrid = <T extends Record<string, any>>( export const useVbenVxeGrid = <T extends Record<string, any>>(

View File

@@ -4,7 +4,6 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { h } from 'vue'; import { h } from 'vue';
import { useVbenForm as useForm } from '@vben/common-ui';
import { import {
setupVbenVxeTable, setupVbenVxeTable,
useVbenVxeGrid as useGrid, useVbenVxeGrid as useGrid,
@@ -68,7 +67,7 @@ setupVbenVxeTable({
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add // vxeUI.formats.add
}, },
useVbenForm: useVbenForm as typeof useForm, useVbenForm,
}); });
export const useVbenVxeGrid = <T extends Record<string, any>>( export const useVbenVxeGrid = <T extends Record<string, any>>(

View File

@@ -4,7 +4,6 @@ import type { ComponentPropsMap, ComponentType } from './component';
import { h } from 'vue'; import { h } from 'vue';
import { useVbenForm as useForm } from '@vben/common-ui';
import { import {
setupVbenVxeTable, setupVbenVxeTable,
useVbenVxeGrid as useGrid, useVbenVxeGrid as useGrid,
@@ -68,7 +67,7 @@ setupVbenVxeTable({
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add // vxeUI.formats.add
}, },
useVbenForm: useVbenForm as typeof useForm, useVbenForm,
}); });
export const useVbenVxeGrid = <T extends Record<string, any>>( export const useVbenVxeGrid = <T extends Record<string, any>>(

View File

@@ -228,7 +228,7 @@ type MappedComponentProps<P> =
) => P & Record<string, any>) ) => P & Record<string, any>)
| (P & Record<string, any>); | (P & Record<string, any>);
interface FormSchemaBody extends FormCommonConfig { interface FormSchemaBody extends Omit<FormCommonConfig, 'componentProps'> {
/** 默认值 */ /** 默认值 */
defaultValue?: any; defaultValue?: any;
/** 依赖 */ /** 依赖 */

View File

@@ -7,7 +7,7 @@ export type ApiComponentOptionsItem = {
children?: ApiComponentOptionsItem[]; children?: ApiComponentOptionsItem[];
disabled?: boolean; disabled?: boolean;
label?: string; label?: string;
value?: string; value?: number | string;
}; };
export interface ApiComponentProps { export interface ApiComponentProps {

View File

@@ -1,6 +1,9 @@
import type { VxeGridInstance } from 'vxe-table'; import type { VxeGridInstance } from 'vxe-table';
import type { ExtendedFormApi } from '@vben-core/form-ui'; import type {
BaseFormComponentType,
ExtendedFormApi,
} from '@vben-core/form-ui';
import type { VxeGridProps } from './types'; import type { VxeGridProps } from './types';
@@ -26,25 +29,29 @@ function getDefaultState(): VxeGridProps {
}; };
} }
export class VxeGridApi<T extends Record<string, any> = any> { export class VxeGridApi<
T extends Record<string, any> = any,
D extends BaseFormComponentType = BaseFormComponentType,
P extends Record<string, any> = Record<never, never>,
> {
public formApi = {} as ExtendedFormApi; public formApi = {} as ExtendedFormApi;
// private prevState: null | VxeGridProps = null; // private prevState: null | VxeGridProps = null;
public grid = {} as VxeGridInstance<T>; public grid = {} as VxeGridInstance<T>;
public state: null | VxeGridProps<T> = null; public state: null | VxeGridProps<T, D, P> = null;
public store: Store<VxeGridProps<T>>; public store: Store<VxeGridProps<T, D, P>>;
private isMounted = false; private isMounted = false;
private stateHandler: StateHandler; private stateHandler: StateHandler;
constructor(options: VxeGridProps = {}) { constructor(options: VxeGridProps<T, D, P> = {} as VxeGridProps<T, D, P>) {
const storeState = { ...options }; const storeState = { ...options };
const defaultState = getDefaultState(); const defaultState = getDefaultState();
this.store = new Store<VxeGridProps>( this.store = new Store<VxeGridProps<T, D, P>>(
mergeWithArrayOverride(storeState, defaultState), mergeWithArrayOverride(storeState, defaultState) as VxeGridProps<T, D, P>,
); );
this.store.subscribe((state) => { this.store.subscribe((state) => {
@@ -82,7 +89,7 @@ export class VxeGridApi<T extends Record<string, any> = any> {
} }
} }
setGridOptions(options: Partial<VxeGridProps['gridOptions']>) { setGridOptions(options: Partial<VxeGridProps<T, D, P>['gridOptions']>) {
this.setState({ this.setState({
gridOptions: options, gridOptions: options,
}); });
@@ -98,8 +105,8 @@ export class VxeGridApi<T extends Record<string, any> = any> {
setState( setState(
stateOrFn: stateOrFn:
| ((prev: VxeGridProps<T>) => Partial<VxeGridProps<T>>) | ((prev: VxeGridProps<T, D, P>) => Partial<VxeGridProps<T, D, P>>)
| Partial<VxeGridProps<T>>, | Partial<VxeGridProps<T, D, P>>,
) { ) {
if (isFunction(stateOrFn)) { if (isFunction(stateOrFn)) {
this.store.setState((prev) => { this.store.setState((prev) => {

View File

@@ -89,9 +89,9 @@ export type ExtendedVxeGridApi<
D extends Record<string, any> = any, D extends Record<string, any> = any,
F extends BaseFormComponentType = BaseFormComponentType, F extends BaseFormComponentType = BaseFormComponentType,
P extends Record<string, any> = Record<never, never>, P extends Record<string, any> = Record<never, never>,
> = VxeGridApi<D> & { > = VxeGridApi<D, F, P> & {
useStore: <S = NoInfer<VxeGridProps<D, F, P>>>( useStore: <S = NoInfer<VxeGridProps<D, F, P>>>(
selector?: (state: NoInfer<VxeGridProps<any, any, any>>) => S, selector?: (state: NoInfer<VxeGridProps<D, F, P>>) => S,
) => Readonly<Ref<S>>; ) => Readonly<Ref<S>>;
}; };

View File

@@ -25,7 +25,7 @@ export function useVbenVxeGrid<
P extends Record<string, any> = Record<never, never>, P extends Record<string, any> = Record<never, never>,
>(options: VxeGridProps<T, D, P>) { >(options: VxeGridProps<T, D, P>) {
// const IS_REACTIVE = isReactive(options); // const IS_REACTIVE = isReactive(options);
const api = new VxeGridApi(options as VxeGridProps); const api = new VxeGridApi<T, D, P>(options);
const extendedApi: ExtendedVxeGridApi<T, D, P> = api as ExtendedVxeGridApi< const extendedApi: ExtendedVxeGridApi<T, D, P> = api as ExtendedVxeGridApi<
T, T,
D, D,
@@ -36,12 +36,21 @@ export function useVbenVxeGrid<
}; };
const Grid = defineComponent( const Grid = defineComponent(
(props: VxeGridProps<T>, { attrs, slots }) => { (props: VxeGridProps<T, D, P>, { attrs, slots }) => {
onBeforeUnmount(() => { onBeforeUnmount(() => {
api.unmount(); api.unmount();
}); });
api.setState({ ...props, ...attrs }); api.setState({ ...props, ...attrs } as Partial<VxeGridProps<T, D, P>>);
return () => h(VxeGrid, { ...props, ...attrs, api: extendedApi }, slots); return () =>
h(
VxeGrid,
{
...props,
...attrs,
api: extendedApi as ExtendedVxeGridApi,
},
slots,
);
}, },
{ {
name: 'VbenVxeGrid', name: 'VbenVxeGrid',

View File

@@ -39,6 +39,7 @@ import type {
IconPickerProps, IconPickerProps,
} from '@vben/common-ui'; } from '@vben/common-ui';
import type { Sortable } from '@vben/hooks'; import type { Sortable } from '@vben/hooks';
import type { TipTapProps } from '@vben/plugins/tiptap';
import type { Recordable } from '@vben/types'; import type { Recordable } from '@vben/types';
import { import {
@@ -69,6 +70,16 @@ import { isEmpty } from '@vben/utils';
import { message, Modal, notification } from 'ant-design-vue'; import { message, Modal, notification } from 'ant-design-vue';
type AdapterUploadProps = UploadProps & {
aspectRatio?: string;
crop?: boolean;
draggable?: boolean;
handleChange?: (event: UploadChangeParam) => void;
maxSize?: number;
onDragSort?: (oldIndex: number, newIndex: number) => void;
onHandleChange?: (event: UploadChangeParam) => void;
};
const AutoComplete = defineAsyncComponent( const AutoComplete = defineAsyncComponent(
() => import('ant-design-vue/es/auto-complete'), () => import('ant-design-vue/es/auto-complete'),
); );
@@ -642,13 +653,14 @@ export interface ComponentPropsMap {
RadioGroup: RadioGroupProps; RadioGroup: RadioGroupProps;
RangePicker: RangePickerProps; RangePicker: RangePickerProps;
Rate: RateProps; Rate: RateProps;
RichEditor: TipTapProps;
Select: SelectProps; Select: SelectProps;
Space: SpaceProps; Space: SpaceProps;
Switch: SwitchProps; Switch: SwitchProps;
Textarea: TextAreaProps; Textarea: TextAreaProps;
TimePicker: TimePickerProps; TimePicker: TimePickerProps;
TreeSelect: TreeSelectProps; TreeSelect: TreeSelectProps;
Upload: UploadProps; Upload: AdapterUploadProps;
} }
async function initComponentAdapter() { async function initComponentAdapter() {