From d6749f95c526c0e71ec946bd3bb777bc42b2c34a Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期日, 20 十月 2024 17:59:31 +0800 Subject: [PATCH] 工艺绑定优化 --- src/components/Form/src/components/FormItem.vue | 135 +++++++++++++++++++++++++++++++++------------ 1 files changed, 99 insertions(+), 36 deletions(-) diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue index 9e598ca..e48f4e9 100644 --- a/src/components/Form/src/components/FormItem.vue +++ b/src/components/Form/src/components/FormItem.vue @@ -2,22 +2,29 @@ import { type Recordable, type Nullable } from '@vben/types'; import type { PropType, Ref } from 'vue'; import { computed, defineComponent, toRefs, unref } from 'vue'; - import type { FormActionType, FormProps, FormSchema } from '../types/form'; - import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; - import type { TableActionType } from '/@/components/Table'; + import { + isComponentFormSchema, + type FormActionType, + type FormProps, + type FormSchemaInner as FormSchema, + } from '../types/form'; + + import type { Rule as ValidationRule } from 'ant-design-vue/lib/form/interface'; + import type { TableActionType } from '@/components/Table'; import { Col, Divider, Form } from 'ant-design-vue'; import { componentMap } from '../componentMap'; - import { BasicHelp } from '/@/components/Basic'; - import { isBoolean, isFunction, isNull } from '/@/utils/is'; - import { getSlot } from '/@/utils/helper/tsxHelper'; + import { BasicHelp, BasicTitle } from '@/components/Basic'; + import { isBoolean, isFunction, isNull } from '@/utils/is'; + import { getSlot } from '@/utils/helper/tsxHelper'; import { createPlaceholderMessage, + isIncludeSimpleComponents, NO_AUTO_LINK_COMPONENTS, setComponentRuleType, } from '../helper'; import { cloneDeep, upperFirst } from 'lodash-es'; import { useItemLabelWidth } from '../hooks/useLabelWidth'; - import { useI18n } from '/@/hooks/web/useI18n'; + import { useI18n } from '@/hooks/web/useI18n'; export default defineComponent({ name: 'BasicFormItem', @@ -61,6 +68,12 @@ formProps: Ref<FormProps>; }; + // 缁勪欢 CropperAvatar 鐨� size 灞炴�х被鍨嬩负 number + // 姝ゅ琛ュ厖涓�涓吋瀹� + if (schema.value.component === 'CropperAvatar' && typeof formProps.value.size === 'string') { + formProps.value.size = undefined; + } + const itemLabelWidthProp = useItemLabelWidth(schema, formProps); const getValues = computed(() => { @@ -84,7 +97,7 @@ if (isFunction(componentProps)) { componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {}; } - if (schema.component === 'Divider') { + if (isIncludeSimpleComponents(schema.component)) { componentProps = Object.assign( { type: 'horizontal' }, { @@ -109,6 +122,21 @@ disabled = dynamicDisabled(unref(getValues)); } return disabled; + }); + + const getReadonly = computed(() => { + const { readonly: globReadonly } = props.formProps; + const { dynamicReadonly } = props.schema; + const { readonly: itemReadonly = false } = unref(getComponentsProps); + + let readonly = globReadonly || itemReadonly; + if (isBoolean(dynamicReadonly)) { + readonly = dynamicReadonly; + } + if (isFunction(dynamicReadonly)) { + readonly = dynamicReadonly(unref(getValues)); + } + return readonly; }); function getShow(): { isShow: boolean; isIfShow: boolean } { @@ -138,7 +166,6 @@ isShow = isShow && itemIsAdvanced; return { isShow, isIfShow }; } - function handleRules(): ValidationRule[] { const { rules: defRules = [], @@ -148,7 +175,6 @@ dynamicRules, required, } = props.schema; - if (isFunction(dynamicRules)) { return dynamicRules(unref(getValues)) as ValidationRule[]; } @@ -159,7 +185,10 @@ const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel') ? rulesMessageJoinLabel : globalRulesMessageJoinLabel; - const defaultMsg = createPlaceholderMessage(component) + `${joinLabel ? label : ''}`; + const assertLabel = joinLabel ? (isFunction(label) ? '' : label) : ''; + const defaultMsg = component + ? createPlaceholderMessage(component) + assertLabel + : assertLabel; function validator(rule: any, value: any) { const msg = rule.message || defaultMsg; @@ -186,7 +215,6 @@ } return Promise.resolve(); } - const getRequired = isFunction(required) ? required(unref(getValues)) : required; /* @@ -196,7 +224,10 @@ */ if (getRequired) { if (!rules || rules.length === 0) { - rules = [{ required: getRequired, validator }]; + const trigger = NO_AUTO_LINK_COMPONENTS.includes(component || 'Input') + ? 'blur' + : 'change'; + rules = [{ required: getRequired, validator, trigger }]; } else { const requiredIndex: number = rules.findIndex((rule) => Reflect.has(rule, 'required')); @@ -217,10 +248,6 @@ rule.required = false; } if (component) { - if (!Reflect.has(rule, 'type')) { - rule.type = component === 'InputNumber' ? 'number' : 'string'; - } - rule.message = rule.message || defaultMsg; if (component.includes('Input') || component.includes('Textarea')) { @@ -242,12 +269,16 @@ } function renderComponent() { + if (!isComponentFormSchema(props.schema)) { + return null; + } const { renderComponentContent, component, field, changeEvent = 'change', valueField, + valueFormat, } = props.schema; const isCheck = component && ['Switch', 'Checkbox'].includes(component); @@ -257,12 +288,17 @@ const on = { [eventKey]: (...args: Nullable<Recordable<any>>[]) => { const [e] = args; + + const target = e ? e.target : null; + let value = target ? (isCheck ? target.checked : target.value) : e; + if(isFunction(valueFormat)){ + value = valueFormat({...unref(getValues),value}); + } + props.setFormModel(field, value, props.schema); + if (propsData[eventKey]) { propsData[eventKey](...args); } - const target = e ? e.target : null; - const value = target ? (isCheck ? target.checked : target.value) : e; - props.setFormModel(field, value, props.schema); }, }; const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>; @@ -270,10 +306,10 @@ const { autoSetPlaceHolder, size } = props.formProps; const propsData: Recordable<any> = { allowClear: true, - getPopupContainer: (trigger: Element) => trigger.parentNode, size, ...unref(getComponentsProps), disabled: unref(getDisable), + readonly: unref(getReadonly), }; const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder; @@ -299,7 +335,12 @@ return <Comp {...compAttr} />; } const compSlot = isFunction(renderComponentContent) - ? { ...renderComponentContent(unref(getValues)) } + ? { + ...renderComponentContent(unref(getValues), { + disabled: unref(getDisable), + readonly: unref(getReadonly), + }), + } : { default: () => renderComponentContent, }; @@ -308,12 +349,13 @@ function renderLabelHelpMessage() { const { label, helpMessage, helpComponentProps, subLabel } = props.schema; + const getLabel = isFunction(label) ? label(unref(getValues)) : label; const renderLabel = subLabel ? ( <span> - {label} <span class="text-secondary">{subLabel}</span> + {getLabel} <span class="text-secondary">{subLabel}</span> </span> ) : ( - label + getLabel ); const getHelpMessage = isFunction(helpMessage) ? helpMessage(unref(getValues)) @@ -330,30 +372,46 @@ } function renderItem() { - const { itemProps, slot, render, field, suffix, component } = props.schema; + const { itemProps, slot, render, field, suffix, component, prefix } = props.schema; const { labelCol, wrapperCol } = unref(itemLabelWidthProp); const { colon } = props.formProps; - + const opts = { disabled: unref(getDisable), readonly: unref(getReadonly) }; if (component === 'Divider') { return ( <Col span={24}> <Divider {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</Divider> </Col> ); + } else if (component === 'BasicTitle') { + return ( + <Form.Item + labelCol={labelCol} + wrapperCol={wrapperCol} + name={field} + class={{ + 'suffix-item': !!suffix, + 'prefix-item': !!prefix, + }} + > + <BasicTitle {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</BasicTitle> + </Form.Item> + ); } else { const getContent = () => { return slot - ? getSlot(slots, slot, unref(getValues)) + ? getSlot(slots, slot, unref(getValues), opts) : render - ? render(unref(getValues)) - : renderComponent(); + ? render(unref(getValues), opts) + : renderComponent(); }; const showSuffix = !!suffix; const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix; + const showPrefix = !!prefix; + const getPrefix = isFunction(prefix) ? prefix(unref(getValues)) : prefix; // TODO 鑷畾涔夌粍浠堕獙璇佷細鍑虹幇闂锛屽洜姝よ繖閲屾鏋堕粯璁ゅ皢鑷畾涔夌粍浠惰缃墜鍔ㄨЕ鍙戦獙璇侊紝濡傛灉鍏朵粬缁勪欢杩樻湁姝ら棶棰樿鎵嬪姩璁剧疆autoLink=false - if (NO_AUTO_LINK_COMPONENTS.includes(component)) { + if (component && NO_AUTO_LINK_COMPONENTS.includes(component)) { props.schema && (props.schema.itemProps! = { autoLink: false, @@ -365,7 +423,10 @@ <Form.Item name={field} colon={colon} - class={{ 'suffix-item': showSuffix }} + class={{ + 'suffix-item': showSuffix, + 'prefix-item': showPrefix, + }} {...(itemProps as Recordable<any>)} label={renderLabelHelpMessage()} rules={handleRules()} @@ -373,6 +434,7 @@ wrapperCol={wrapperCol} > <div style="display:flex"> + {showPrefix && <span class="prefix">{getPrefix}</span>} <div style="flex:1;">{getContent()}</div> {showSuffix && <span class="suffix">{getSuffix}</span>} </div> @@ -382,8 +444,8 @@ } return () => { - const { colProps = {}, colSlot, renderColContent, component } = props.schema; - if (!componentMap.has(component)) { + const { colProps = {}, colSlot, renderColContent, component, slot } = props.schema; + if (!((component && componentMap.has(component)) || slot)) { return null; } @@ -391,13 +453,14 @@ const realColProps = { ...baseColProps, ...colProps }; const { isIfShow, isShow } = getShow(); const values = unref(getValues); + const opts = { disabled: unref(getDisable), readonly: unref(getReadonly) }; const getContent = () => { return colSlot - ? getSlot(slots, colSlot, values) + ? getSlot(slots, colSlot, values, opts) : renderColContent - ? renderColContent(values) - : renderItem(); + ? renderColContent(values, opts) + : renderItem(); }; return ( -- Gitblit v1.9.3