From 9dfa701454d6a94690bad39dbb0e38f2a0b31489 Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期二, 18 六月 2024 18:08:47 +0800 Subject: [PATCH] build --- src/components/Form/src/hooks/useFormEvents.ts | 310 ++++++++++++++++++++++++++++++++------------------- 1 files changed, 192 insertions(+), 118 deletions(-) diff --git a/src/components/Form/src/hooks/useFormEvents.ts b/src/components/Form/src/hooks/useFormEvents.ts index 028c314..a664ae9 100644 --- a/src/components/Form/src/hooks/useFormEvents.ts +++ b/src/components/Form/src/hooks/useFormEvents.ts @@ -1,21 +1,19 @@ import type { ComputedRef, Ref } from 'vue'; -import type { FormProps, FormSchema, FormActionType } from '../types/form'; +import type { FormProps, FormSchemaInner as FormSchema, FormActionType } from '../types/form'; import type { NamePath } from 'ant-design-vue/lib/form/interface'; import { unref, toRaw, nextTick } from 'vue'; +import { isArray, isFunction, isObject, isString, isNil } from '@/utils/is'; +import { deepMerge } from '@/utils'; import { - isArray, - isFunction, - isObject, - isString, - isDef, - isNullOrUnDef, - isEmpty, -} from '/@/utils/is'; -import { deepMerge } from '/@/utils'; -import { dateItemType, handleInputNumberValue, defaultValueComponents } from '../helper'; -import { dateUtil } from '/@/utils/dateUtil'; -import { cloneDeep, set, uniqBy, get } from 'lodash-es'; -import { error } from '/@/utils/log'; + dateItemType, + defaultValueComponents, + isIncludeSimpleComponents, + uploadItemType, +} from '../helper'; +import { dateUtil } from '@/utils/dateUtil'; +import { cloneDeep, has, uniqBy, get, set } from 'lodash-es'; +import { error } from '@/utils/log'; +import { ComponentProps } from '../types'; interface UseFormActionContext { emit: EmitType; @@ -27,7 +25,12 @@ schemaRef: Ref<FormSchema[]>; handleFormValues: Fn; } - + /** + * @description: Is it upload + */ + export function itemIsUploadComponent(key: keyof ComponentProps) { + return uploadItemType.includes(key); + } function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined { const pattern = /^\[(.+)\]$/; if (pattern.test(field)) { @@ -37,37 +40,14 @@ if (!keys.length) { return undefined; } - const result = []; keys.forEach((k, index) => { set(result, index, values[k.trim()]); }); - return result.filter(Boolean).length ? result : undefined; } } } - -function tryConstructObject(field: string, values: Recordable = {}): Recordable | undefined { - const pattern = /^\{(.+)\}$/; - if (pattern.test(field)) { - const match = field.match(pattern); - if (match && match[1]) { - const keys = match[1].split(','); - if (!keys.length) { - return; - } - - const result = {}; - keys.forEach((k) => { - set(result, k.trim(), values[k.trim()]); - }); - - return Object.values(result).filter(Boolean).length ? result : undefined; - } - } -} - export function useFormEvents({ emit, getProps, @@ -87,83 +67,123 @@ Object.keys(formModel).forEach((key) => { const schema = unref(getSchema).find((item) => item.field === key); - const isInput = schema?.component && defaultValueComponents.includes(schema.component); - const defaultValue = cloneDeep(defaultValueRef.value[key]); - formModel[key] = isInput ? defaultValue || '' : defaultValue; + const defaultValueObj = schema?.defaultValueObj; + const fieldKeys = Object.keys(defaultValueObj || {}); + if (fieldKeys.length) { + fieldKeys.forEach((field) => { + formModel[field] = defaultValueObj![field]; + }); + } + formModel[key] = getDefaultValue(schema, defaultValueRef, key); }); nextTick(() => clearValidate()); emit('reset', toRaw(formModel)); 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<void> { - const fields = unref(getSchema) - .map((item) => item.field) - .filter(Boolean); + if (Object.keys(values).length === 0) { + return; + } - // key 鏀寔 a.b.c 鐨勫祵濂楀啓娉� - const delimiter = '.'; - const nestKeyArray = fields.filter((item) => String(item).indexOf(delimiter) >= 0); + const fields = getAllFields(); const validKeys: string[] = []; fields.forEach((key) => { const schema = unref(getSchema).find((item) => item.field === key); - let value = get(values, key); - const hasKey = Reflect.has(values, key); - - value = handleInputNumberValue(schema?.component, value); + const value = get(values, key); + const hasKey = has(values, key); const { componentProps } = schema || {}; let _props = componentProps as any; if (typeof componentProps === 'function') { - _props = _props({ formModel: unref(formModel) }); + _props = _props({ + formModel: unref(formModel), + formActionType, + }); } - const constructValue = tryConstructArray(key, values) || tryConstructObject(key, values); + let constructValue; + const setDateFieldValue = (v) => { + return v ? (_props?.valueFormat ? v : dateUtil(v)) : null; + }; - // 0| '' is allow - if (hasKey || !!constructValue) { - const fieldValue = constructValue || value; - // time type - if (itemIsDateType(key)) { + // Adapt date component + if (itemIsDateComponent(schema?.component)) { + constructValue = tryConstructArray(key, values); + if (constructValue) { + const fieldValue = constructValue || value; if (Array.isArray(fieldValue)) { const arr: any[] = []; for (const ele of fieldValue) { - arr.push(ele ? dateUtil(ele) : null); + arr.push(setDateFieldValue(ele)); } unref(formModel)[key] = arr; + validKeys.push(key); } else { - unref(formModel)[key] = fieldValue - ? _props?.valueFormat - ? fieldValue - : dateUtil(fieldValue) - : null; + unref(formModel)[key] = setDateFieldValue(fieldValue); + validKeys.push(key); } - } else { - unref(formModel)[key] = fieldValue; } + } + // Adapt upload component + if (itemIsUploadComponent(schema?.component)) { + constructValue = get(value, key); + const fieldValue = constructValue || value; + if (fieldValue) { + if (isArray(fieldValue)) { + unref(formModel)[key] = fieldValue; + } else if (typeof fieldValue == 'string') { + unref(formModel)[key] = [fieldValue]; + } + } + validKeys.push(key); + return + } + // Adapt common component + if (hasKey) { + constructValue = get(value, key); + const fieldValue = constructValue || value; + unref(formModel)[key] = fieldValue; if (_props?.onChange) { _props?.onChange(fieldValue); } validKeys.push(key); } else { - nestKeyArray.forEach((nestKey: string) => { - try { - const value = nestKey.split('.').reduce((out, item) => out[item], values); - if (isDef(value)) { - unref(formModel)[nestKey] = unref(value); - validKeys.push(nestKey); - } - } catch (e) { - // key not exist - if (isDef(defaultValueRef.value[nestKey])) { - unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey])); - } - } - }); + // key not exist + // refer:https://github.com/vbenjs/vue-vben-admin/issues/3795 + } + }); + validateFields(validKeys).catch((_) => {}); + } + + /** + * @description: Set form default value + */ + function resetDefaultField(nameList?: NamePath[]) { + if (!Array.isArray(nameList)) { + return; + } + if (Array.isArray(nameList) && nameList.length === 0) { + return; + } + const validKeys: string[] = []; + const keys = Object.keys(unref(formModel)); + if (!keys) { + return; + } + nameList.forEach((key: any) => { + if (keys.includes(key)) { + validKeys.push(key); + unref(formModel)[key] = cloneDeep(unref(get(defaultValueRef.value, key))); } }); validateFields(validKeys).catch((_) => {}); @@ -178,12 +198,12 @@ return; } - let fieldList: string[] = isString(fields) ? [fields] : fields; + let fieldList = (isString(fields) ? [fields] : fields) as string[]; if (isString(fields)) { - fieldList = [fields]; + fieldList = [fields as string]; } for (const field of fieldList) { - _removeSchemaByFeild(field, schemaList); + _removeSchemaByField(field, schemaList); } schemaRef.value = schemaList; } @@ -191,7 +211,7 @@ /** * @description: Delete based on field name */ - function _removeSchemaByFeild(field: string, schemaList: FormSchema[]): void { + function _removeSchemaByField(field: string, schemaList: FormSchema[]): void { if (isString(field)) { const index = schemaList.findIndex((schema) => schema.field === field); if (index !== -1) { @@ -210,21 +230,22 @@ first = false, ) { const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); - + const addSchemaIds: string[] = Array.isArray(schema) + ? schema.map((item) => item.field) + : [schema.field]; + if (schemaList.find((item) => addSchemaIds.includes(item.field))) { + error('There are schemas that have already been added'); + return; + } const index = schemaList.findIndex((schema) => schema.field === prefixField); const _schemaList = isObject(schema) ? [schema as FormSchema] : (schema as FormSchema[]); if (!prefixField || index === -1 || first) { first ? schemaList.unshift(..._schemaList) : schemaList.push(..._schemaList); - schemaRef.value = schemaList; - _setDefaultValue(schema); - return; - } - if (index !== -1) { + } else if (index !== -1) { schemaList.splice(index + 1, 0, ..._schemaList); } - _setDefaultValue(schema); - schemaRef.value = schemaList; + _setDefaultValue(schema); } async function resetSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) { @@ -237,7 +258,8 @@ } const hasField = updateData.every( - (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field), + (item) => + isIncludeSimpleComponents(item.component) || (Reflect.has(item, 'field') && item.field), ); if (!hasField) { @@ -259,7 +281,8 @@ } const hasField = updateData.every( - (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field), + (item) => + isIncludeSimpleComponents(item.component) || (Reflect.has(item, 'field') && item.field), ); if (!hasField) { @@ -269,21 +292,19 @@ return; } const schema: FormSchema[] = []; + const updatedSchema: FormSchema[] = []; unref(getSchema).forEach((val) => { - let _val; - updateData.forEach((item) => { - if (val.field === item.field) { - _val = item; - } - }); - if (_val !== undefined && val.field === _val.field) { - const newSchema = deepMerge(val, _val); + const updatedItem = updateData.find((item) => val.field === item.field); + + if (updatedItem) { + const newSchema = deepMerge(val, updatedItem); + updatedSchema.push(newSchema as FormSchema); schema.push(newSchema as FormSchema); } else { schema.push(val); } }); - _setDefaultValue(schema); + _setDefaultValue(updatedSchema); schemaRef.value = uniqBy(schema, 'field'); } @@ -301,13 +322,11 @@ const currentFieldsValue = getFieldsValue(); schemas.forEach((item) => { if ( - item.component != 'Divider' && + !isIncludeSimpleComponents(item.component) && Reflect.has(item, 'field') && item.field && - !isNullOrUnDef(item.defaultValue) && - (!(item.field in currentFieldsValue) || - isNullOrUnDef(currentFieldsValue[item.field]) || - isEmpty(currentFieldsValue[item.field])) + !isNil(item.defaultValue) && + (!(item.field in currentFieldsValue) || isNil(currentFieldsValue[item.field])) ) { obj[item.field] = item.defaultValue; } @@ -324,18 +343,28 @@ /** * @description: Is it time */ - function itemIsDateType(key: string) { - return unref(getSchema).some((item) => { - return item.field === key ? dateItemType.includes(item.component) : false; - }); + function itemIsDateComponent(key: string) { + return dateItemType.includes(key); } async function validateFields(nameList?: NamePath[] | undefined) { - return unref(formElRef)?.validateFields(nameList); + const values = await unref(formElRef)?.validateFields(nameList); + return handleFormValues(values); } - async function validate(nameList?: NamePath[] | undefined) { - return await unref(formElRef)?.validate(nameList); + async function setProps(formProps: Partial<FormProps>): Promise<void> { + await unref(formElRef)?.setProps(formProps); + } + + async function validate(nameList?: NamePath[] | false | undefined) { + let _nameList: any; + if (nameList === undefined) { + _nameList = getAllFields(); + } else { + _nameList = nameList === Array.isArray(nameList) ? nameList : undefined; + } + const values = await unref(formElRef)?.validate(_nameList); + return handleFormValues(values); } async function clearValidate(name?: string | string[]) { @@ -360,8 +389,7 @@ if (!formEl) return; try { const values = await validate(); - const res = handleFormValues(values); - emit('submit', res); + emit('submit', values); } catch (error: any) { if (error?.outOfDate === false && error?.errorFields) { return; @@ -369,6 +397,22 @@ throw new Error(error); } } + + const formActionType: Partial<FormActionType> = { + getFieldsValue, + setFieldsValue, + resetFields, + updateSchema, + resetSchema, + setProps, + removeSchemaByField, + appendSchemaByField, + clearValidate, + validateFields, + validate, + submit: handleSubmit, + scrollToField: scrollToField, + }; return { handleSubmit, @@ -383,5 +427,35 @@ resetFields, setFieldsValue, scrollToField, + resetDefaultField, }; } + +function getDefaultValue( + schema: FormSchema | undefined, + defaultValueRef: UseFormActionContext['defaultValueRef'], + key: string, +) { + let defaultValue = cloneDeep(defaultValueRef.value[key]); + const isInput = checkIsInput(schema); + if (isInput) { + return !isNil(defaultValue) ? defaultValue : undefined; + } + if (!defaultValue && schema && checkIsRangeSlider(schema)) { + defaultValue = [0, 0]; + } + if (!defaultValue && schema && schema.component === 'ApiTree') { + defaultValue = []; + } + return defaultValue; +} + +function checkIsRangeSlider(schema: FormSchema) { + if (schema.component === 'Slider' && schema.componentProps && 'range' in schema.componentProps) { + return true; + } +} + +function checkIsInput(schema?: FormSchema) { + return schema?.component && defaultValueComponents.includes(schema.component); +} -- Gitblit v1.9.3