diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue index 3901f9a9..a28b4d6f 100644 --- a/src/components/Form/src/components/FormItem.vue +++ b/src/components/Form/src/components/FormItem.vue @@ -272,7 +272,7 @@ export default defineComponent({ return const compSlot = isFunction(renderComponentContent) - ? { ...renderComponentContent(unref(getValues)) } + ? { ...renderComponentContent(unref(getValues), { disabled: unref(getDisable) }) } : { default: () => renderComponentContent, } @@ -307,6 +307,8 @@ export default defineComponent({ const { labelCol, wrapperCol } = unref(itemLabelWidthProp) const { colon } = props.formProps + const opts = { disabled: unref(getDisable) } + if (component === 'Divider') { return ( @@ -316,7 +318,7 @@ export default defineComponent({ } else { const getContent = () => { - return slot ? getSlot(slots, slot, unref(getValues)) : render ? render(unref(getValues)) : renderComponent() + return slot ? getSlot(slots, slot, unref(getValues), opts) : render ? render(unref(getValues), opts) : renderComponent() } const showSuffix = !!suffix @@ -360,9 +362,10 @@ export default defineComponent({ const realColProps = { ...baseColProps, ...colProps } const { isIfShow, isShow } = getShow() const values = unref(getValues) + const opts = { disabled: unref(getDisable) } const getContent = () => { - return colSlot ? getSlot(slots, colSlot, values) : renderColContent ? renderColContent(values) : renderItem() + return colSlot ? getSlot(slots, colSlot, values, opts) : renderColContent ? renderColContent(values, opts) : renderItem() } return ( diff --git a/src/components/Form/src/hooks/useFormEvents.ts b/src/components/Form/src/hooks/useFormEvents.ts index 234cb12c..39ac8509 100644 --- a/src/components/Form/src/hooks/useFormEvents.ts +++ b/src/components/Form/src/hooks/useFormEvents.ts @@ -78,6 +78,13 @@ export function useFormEvents({ Object.keys(formModel).forEach((key) => { const schema = unref(getSchema).find(item => item.field === key) + const defaultValueObj = schema?.defaultValueObj + const fieldKeys = Object.keys(defaultValueObj || {}) + if (fieldKeys.length) { + fieldKeys.map((field) => { + formModel[field] = defaultValueObj[field] + }) + } const isInput = schema?.component && defaultValueComponents.includes(schema.component) const defaultValue = cloneDeep(defaultValueRef.value[key]) formModel[key] = isInput ? defaultValue || '' : defaultValue @@ -88,13 +95,18 @@ export function useFormEvents({ submitOnReset && handleSubmit() } + // 获取表单fields + const getAllFields = () => + unref(getSchema) + .map(item => [...(item.fields || []), item.field]) + .flat(1) + .filter(Boolean) + /** * @description: Set form value */ async function setFieldsValue(values: Recordable): Promise { - const fields = unref(getSchema) - .map(item => item.field) - .filter(Boolean) + const fields = getAllFields() // key 支持 a.b.c 的嵌套写法 const delimiter = '.' @@ -305,8 +317,15 @@ export function useFormEvents({ return unref(formElRef)?.validateFields(nameList) } - async function validate(nameList?: NamePath[] | undefined) { - return await unref(formElRef)?.validate(nameList) + async function validate(nameList?: NamePath[] | false | undefined) { + let _nameList: any + if (nameList === undefined) + _nameList = getAllFields() + + else + _nameList = nameList === Array.isArray(nameList) ? nameList : undefined + + return await unref(formElRef)?.validate(_nameList) } async function clearValidate(name?: string | string[]) { diff --git a/src/components/Form/src/hooks/useFormValues.ts b/src/components/Form/src/hooks/useFormValues.ts index 62599873..a3ddabe4 100644 --- a/src/components/Form/src/hooks/useFormValues.ts +++ b/src/components/Form/src/hooks/useFormValues.ts @@ -119,7 +119,15 @@ export function useFormValues({ defaultValueRef, getSchema, formModel, getProps const schemas = unref(getSchema) const obj: Recordable = {} schemas.forEach((item) => { - const { defaultValue } = item + const { defaultValue, defaultValueObj } = item + const fieldKeys = Object.keys(defaultValueObj || {}) + if (fieldKeys.length) { + fieldKeys.map((field) => { + obj[field] = defaultValueObj[field] + if (formModel[field] === undefined) + formModel[field] = defaultValueObj[field] + }) + } if (!isNullOrUnDef(defaultValue)) { obj[item.field] = defaultValue diff --git a/src/components/Form/src/types/form.ts b/src/components/Form/src/types/form.ts index 6ca6a3a0..e3d31e44 100644 --- a/src/components/Form/src/types/form.ts +++ b/src/components/Form/src/types/form.ts @@ -35,7 +35,7 @@ export interface FormActionType { removeSchemaByField: (field: string | string[]) => Promise appendSchemaByField: (schema: FormSchema | FormSchema[], prefixField: string | undefined, first?: boolean | undefined) => Promise validateFields: (nameList?: NamePath[]) => Promise - validate: (nameList?: NamePath[]) => Promise + validate: (nameList?: NamePath[] | false) => Promise scrollToField: (name: NamePath, options?: ScrollOptions) => Promise } @@ -119,15 +119,21 @@ export interface FormProps { transformDateFunc?: (date: any) => string colon?: boolean } +export interface RenderOpts { + disabled: boolean + [key: string]: any +} export interface FormSchema { // Field name field: string + // Extra Fields name[] + fields?: string[] // Event name triggered by internal value change, default change changeEvent?: string // Variable name bound to v-model Default value valueField?: string // Label name - label: string | VNode + label?: string | VNode // Auxiliary text subLabel?: string // Help text on the right side of the text @@ -163,6 +169,9 @@ export interface FormSchema { // 默认值 defaultValue?: any + // 额外默认值数组对象 + defaultValueObj?: { [key: string]: any } + // 是否自动处理与时间相关组件的默认值 isHandleDateDefaultValue?: boolean @@ -176,12 +185,18 @@ export interface FormSchema { show?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean) // Render the content in the form-item tag - render?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string + render?: ( + renderCallbackParams: RenderCallbackParams, + opts: RenderOpts, + ) => VNode | VNode[] | string // Rendering col content requires outer wrapper form-item - renderColContent?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string + renderColContent?: ( + renderCallbackParams: RenderCallbackParams, + opts: RenderOpts, + ) => VNode | VNode[] | string - renderComponentContent?: ((renderCallbackParams: RenderCallbackParams) => any) | VNode | VNode[] | string + renderComponentContent?: ((renderCallbackParams: RenderCallbackParams, opts: RenderOpts) => any) | VNode | VNode[] | string // Custom slot, in from-item slot?: string diff --git a/src/utils/helper/tsxHelper.tsx b/src/utils/helper/tsxHelper.tsx index 0c54df87..ec8adf27 100644 --- a/src/utils/helper/tsxHelper.tsx +++ b/src/utils/helper/tsxHelper.tsx @@ -1,10 +1,11 @@ import type { Slots } from 'vue' import { isFunction } from '@/utils/is' +import type { RenderOpts } from '@/components/Form' /** * @description: Get slot to prevent empty error */ -export function getSlot(slots: Slots, slot = 'default', data?: any) { +export function getSlot(slots: Slots, slot = 'default', data?: any, opts?: RenderOpts) { if (!slots || !Reflect.has(slots, slot)) return null @@ -15,7 +16,8 @@ export function getSlot(slots: Slots, slot = 'default', data?: any) { const slotFn = slots[slot] if (!slotFn) return null - return slotFn(data) + const params = { ...data, ...opts } + return slotFn(params) } /**