fix: formItem error repeat show, close #5349

pull/5361/head
tangjinzhou 3 years ago
parent c69cf76d3c
commit ee6d489bf4

@ -34,6 +34,7 @@ import FormItemLabel from './FormItemLabel';
import FormItemInput from './FormItemInput'; import FormItemInput from './FormItemInput';
import type { ValidationRule } from './Form'; import type { ValidationRule } from './Form';
import { useProvideFormItemContext } from './FormItemContext'; import { useProvideFormItemContext } from './FormItemContext';
import useDebounce from './utils/useDebounce';
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', ''); const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
export type ValidateStatus = typeof ValidateStatuses[number]; export type ValidateStatus = typeof ValidateStatuses[number];
@ -368,15 +369,24 @@ export default defineComponent({
onBeforeUnmount(() => { onBeforeUnmount(() => {
formContext.removeField(eventKey); formContext.removeField(eventKey);
}); });
const debounceErrors = useDebounce(errors);
const mergedValidateStatus = computed(() => {
if (props.validateStatus !== undefined) {
return props.validateStatus;
} else if (debounceErrors.value.length) {
return 'error';
}
return validateState.value;
});
const itemClassName = computed(() => ({ const itemClassName = computed(() => ({
[`${prefixCls.value}-item`]: true, [`${prefixCls.value}-item`]: true,
// Status // Status
[`${prefixCls.value}-item-has-feedback`]: validateState.value && props.hasFeedback, [`${prefixCls.value}-item-has-feedback`]: mergedValidateStatus.value && props.hasFeedback,
[`${prefixCls.value}-item-has-success`]: validateState.value === 'success', [`${prefixCls.value}-item-has-success`]: mergedValidateStatus.value === 'success',
[`${prefixCls.value}-item-has-warning`]: validateState.value === 'warning', [`${prefixCls.value}-item-has-warning`]: mergedValidateStatus.value === 'warning',
[`${prefixCls.value}-item-has-error`]: validateState.value === 'error', [`${prefixCls.value}-item-has-error`]: mergedValidateStatus.value === 'error',
[`${prefixCls.value}-item-is-validating`]: validateState.value === 'validating', [`${prefixCls.value}-item-is-validating`]: mergedValidateStatus.value === 'validating',
[`${prefixCls.value}-item-hidden`]: props.hidden, [`${prefixCls.value}-item-hidden`]: props.hidden,
})); }));
return () => { return () => {
@ -387,7 +397,7 @@ export default defineComponent({
{...attrs} {...attrs}
class={[ class={[
itemClassName.value, itemClassName.value,
(help !== undefined && help !== null) || errors.value.length (help !== undefined && help !== null) || debounceErrors.value.length
? `${prefixCls.value}-item-with-help` ? `${prefixCls.value}-item-with-help`
: '', : '',
attrs.class, attrs.class,
@ -409,10 +419,11 @@ export default defineComponent({
{/* Input Group */} {/* Input Group */}
<FormItemInput <FormItemInput
{...props} {...props}
errors={help !== undefined && help !== null ? toArray(help) : errors.value} errors={
help !== undefined && help !== null ? toArray(help) : debounceErrors.value
}
prefixCls={prefixCls.value} prefixCls={prefixCls.value}
status={validateState.value} status={mergedValidateStatus.value}
validateStatus={validateState.value}
ref={inputRef} ref={inputRef}
help={help} help={help}
extra={props.extra ?? slots.extra?.()} extra={props.extra ?? slots.extra?.()}

@ -40,7 +40,6 @@ const FormItemInput = defineComponent({
'prefixCls', 'prefixCls',
'errors', 'errors',
'hasFeedback', 'hasFeedback',
'validateStatus',
'onDomErrorVisibleChange', 'onDomErrorVisibleChange',
'wrapperCol', 'wrapperCol',
'help', 'help',
@ -68,7 +67,7 @@ const FormItemInput = defineComponent({
help = slots.help?.(), help = slots.help?.(),
errors = slots.errors?.(), errors = slots.errors?.(),
hasFeedback, hasFeedback,
validateStatus, status,
extra = slots.extra?.(), extra = slots.extra?.(),
} = props; } = props;
const baseClassName = `${prefixCls}-item`; const baseClassName = `${prefixCls}-item`;
@ -79,7 +78,7 @@ const FormItemInput = defineComponent({
const className = classNames(`${baseClassName}-control`, mergedWrapperCol.class); const className = classNames(`${baseClassName}-control`, mergedWrapperCol.class);
// Should provides additional icon if `hasFeedback` // Should provides additional icon if `hasFeedback`
const IconNode = validateStatus && iconMap[validateStatus]; const IconNode = status && iconMap[status];
return ( return (
<Col <Col

@ -0,0 +1,18 @@
import type { Ref } from 'vue';
import { shallowRef, watchEffect } from 'vue';
export default function useDebounce<T>(value: Ref<T[]>): Ref<T[]> {
const cacheValue = shallowRef(value.value.slice());
let timeout: any = null;
watchEffect(() => {
clearTimeout(timeout);
timeout = setTimeout(
() => {
cacheValue.value = value.value;
},
value.value.length ? 0 : 10,
);
});
return cacheValue;
}
Loading…
Cancel
Save