diff --git a/docs/src/components/common-ui/vben-form.md b/docs/src/components/common-ui/vben-form.md index 112bb844965..1c994192d92 100644 --- a/docs/src/components/common-ui/vben-form.md +++ b/docs/src/components/common-ui/vben-form.md @@ -365,6 +365,10 @@ export interface ActionButtonOptions { ```ts export interface FormCommonConfig { + /** + * 是否自动赋值 + */ + autoDefaultValue?: boolean; /** * 所有表单项的props */ diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue index 5233019b6b7..d17b358ffb5 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue +++ b/packages/@core/ui-kit/form-ui/src/form-render/form-field.vue @@ -3,7 +3,7 @@ import type { ZodType } from 'zod'; import type { FormSchema, MaybeComponentProps } from '../types'; -import { computed, nextTick, useTemplateRef, watch } from 'vue'; +import { computed, nextTick, onMounted, useTemplateRef, watch } from 'vue'; import { FormControl, @@ -26,10 +26,12 @@ import { isEventObjectLike } from './helper'; interface Props extends FormSchema {} const { + autoDefaultValue = false, colon, commonComponentProps, component, componentProps, + defaultValue, dependencies, description, disabled, @@ -163,6 +165,16 @@ const computedProps = computed(() => { ...dynamicComponentProps.value, }; }); +const computedItemProps = computed(() => { + const finalComponentProps = isFunction(componentProps) + ? componentProps(values.value, formApi!) + : componentProps; + + return { + ...finalComponentProps, + ...dynamicComponentProps.value, + }; +}); watch( () => computedProps.value?.autofocus, @@ -201,6 +213,23 @@ const fieldProps = computed(() => { }; }); +onMounted(() => { + if ( + autoDefaultValue && + Reflect.has(commonComponentProps, 'change') && + defaultValue + ) { + const value = (formApi && formApi.values[fieldName]) ?? defaultValue; + commonComponentProps.change(value, { + e: value, + ...computedProps.value, + emptyStateValue, + formApi, + name: fieldName, + }); + } +}); + function fieldBindEvent(slotProps: Record) { const modelValue = slotProps.componentField.modelValue; const handler = slotProps.componentField['onUpdate:modelValue']; @@ -210,6 +239,19 @@ function fieldBindEvent(slotProps: Record) { (isString(component) ? componentBindEventMap.value?.[component] : null); let value = modelValue; + + const change = (...e: any) => { + handler(...e); + if (Reflect.has(commonComponentProps, 'change')) { + commonComponentProps.change(e[0], { + e, + ...slotProps.componentField, + ...computedProps.value, + [bindEventField || '']: value === undefined ? emptyStateValue : value, + formApi, + }); + } + }; // antd design 的一些组件会传递一个 event 对象 if (modelValue && isObject(modelValue) && bindEventField) { value = isEventObjectLike(modelValue) @@ -219,7 +261,7 @@ function fieldBindEvent(slotProps: Record) { if (bindEventField) { return { - [`onUpdate:${bindEventField}`]: handler, + [`onUpdate:${bindEventField}`]: change, [bindEventField]: value === undefined ? emptyStateValue : value, onChange: disabledOnChangeListener ? undefined @@ -243,17 +285,42 @@ function fieldBindEvent(slotProps: Record) { function createComponentProps(slotProps: Record) { const bindEvents = fieldBindEvent(slotProps); - - const binds = { + const assginData = { ...slotProps.componentField, ...computedProps.value, ...bindEvents, + }; + + const change = (key: string, value: any, ...e: any) => { + if (!Reflect.has(assginData, key)) return; + (assginData as any)[key](...e); + + nextTick(() => { + if (Reflect.has(computedItemProps.value, 'change')) { + computedItemProps.value.change(value, { + e, + ...slotProps.componentField, + ...computedProps.value, + ...bindEvents, + formApi, + }); + } + }); + }; + const binds = { + ...assginData, ...(Reflect.has(computedProps.value, 'onChange') - ? { onChange: computedProps.value.onChange } + ? { onChange: (...e: any) => change('onChange', e[0], ...e) } : {}), ...(Reflect.has(computedProps.value, 'onInput') - ? { onInput: computedProps.value.onInput } + ? { onInput: (...e: any) => change('onInput', e[0], ...e) } : {}), + 'onUpdate:modelValue': (...e: any) => { + change('onUpdate:modelValue', e[0], ...e); + }, + 'onUpdate:value': (...e: any) => { + change('onUpdate:value', e[0], ...e); + }, }; return binds; diff --git a/packages/@core/ui-kit/form-ui/src/form-render/form.vue b/packages/@core/ui-kit/form-ui/src/form-render/form.vue index ff827c42a09..9ecb2cd4dbe 100644 --- a/packages/@core/ui-kit/form-ui/src/form-render/form.vue +++ b/packages/@core/ui-kit/form-ui/src/form-render/form.vue @@ -85,6 +85,7 @@ const computedSchema = computed( formFieldProps: Record; })[] => { const { + autoDefaultValue = false, colon = false, componentProps = {}, controlClass = '', @@ -111,6 +112,7 @@ const computedSchema = computed( : false; return { + autoDefaultValue, colon, disabled, disabledOnChangeListener, diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts index 57b2a68b817..47a4e8a50cc 100644 --- a/packages/@core/ui-kit/form-ui/src/types.ts +++ b/packages/@core/ui-kit/form-ui/src/types.ts @@ -137,6 +137,10 @@ type ComponentProps = | MaybeComponentProps; export interface FormCommonConfig { + /** + * 是否自动赋值 + */ + autoDefaultValue?: boolean; /** * 在Label后显示一个冒号 */