feat: formate validateFields values #4964

This commit is contained in:
tangjinzhou 2021-12-03 22:36:59 +08:00
parent c07e3f0831
commit 5265440f76
4 changed files with 99 additions and 13 deletions

View File

@ -5,7 +5,7 @@ import classNames from '../_util/classNames';
import warning from '../_util/warning';
import type { FieldExpose } from './FormItem';
import FormItem from './FormItem';
import { getNamePath, containsNamePath } from './utils/valueUtil';
import { getNamePath, containsNamePath, cloneByNamePathList } from './utils/valueUtil';
import { defaultValidateMessages } from './utils/messages';
import { allPromiseFinish } from './utils/asyncUtil';
import { toArray } from './utils/typeUtil';
@ -133,7 +133,6 @@ const Form = defineComponent({
);
const lastValidatePromise = ref();
const fields: Record<string, FieldExpose> = {};
const addField = (eventKey: string, field: FieldExpose) => {
fields[eventKey] = field;
};
@ -197,19 +196,15 @@ const Form = defineComponent({
}
};
// eslint-disable-next-line no-unused-vars
const getFieldsValue = (nameList: NamePath[] | true = true) => {
const values: any = {};
Object.values(fields).forEach(({ fieldName, fieldValue }) => {
values[fieldName.value] = fieldValue.value;
});
const getFieldsValue = (nameList: InternalNamePath[] | true = true) => {
if (nameList === true) {
return values;
const allNameList = [];
Object.values(fields).forEach(({ namePath }) => {
allNameList.push(namePath.value);
});
return cloneByNamePathList(props.model, allNameList);
} else {
const res: any = {};
toArray(nameList as NamePath[]).forEach(
namePath => (res[namePath as string] = values[namePath as string]),
);
return res;
return cloneByNamePathList(props.model, nameList);
}
};
const validateFields = (nameList?: NamePath[], options?: ValidateOptions) => {

View File

@ -1,5 +1,7 @@
import { toArray } from './typeUtil';
import type { InternalNamePath, NamePath } from '../interface';
import get from '../../vc-util/get';
import set from '../../vc-util/set';
/**
* Convert name to internal supported format.
@ -12,6 +14,21 @@ export function getNamePath(path: NamePath | null): InternalNamePath {
return toArray(path);
}
export function getValue<T>(store: T, namePath: InternalNamePath) {
const value = get(store, namePath);
return value;
}
export function setValue<T>(
store: T,
namePath: InternalNamePath,
value: any,
removeIfUndefined = false,
): T {
const newStore = set(store, namePath, value, removeIfUndefined);
return newStore;
}
export function containsNamePath(namePathList: InternalNamePath[], namePath: InternalNamePath) {
return namePathList && namePathList.some(path => matchNamePath(path, namePath));
}
@ -50,6 +67,16 @@ export function setValues<T>(store: T, ...restValues: T[]): T {
);
}
export function cloneByNamePathList<T>(store: T, namePathList: InternalNamePath[]): T {
let newStore = {} as T;
namePathList.forEach(namePath => {
const value = getValue(store, namePath);
newStore = setValue(newStore, namePath, value);
});
return newStore;
}
export function matchNamePath(
namePath: InternalNamePath,
changedNamePath: InternalNamePath | null,

13
components/vc-util/get.ts Normal file
View File

@ -0,0 +1,13 @@
export default function get(entity: any, path: (string | number)[]) {
let current = entity;
for (let i = 0; i < path.length; i += 1) {
if (current === null || current === undefined) {
return undefined;
}
current = current[path[i]];
}
return current;
}

51
components/vc-util/set.ts Normal file
View File

@ -0,0 +1,51 @@
import get from './get';
function internalSet<Entity = any, Output = Entity, Value = any>(
entity: Entity,
paths: (string | number)[],
value: Value,
removeIfUndefined: boolean,
): Output {
if (!paths.length) {
return value as unknown as Output;
}
const [path, ...restPath] = paths;
let clone: Output;
if (!entity && typeof path === 'number') {
clone = [] as unknown as Output;
} else if (Array.isArray(entity)) {
clone = [...entity] as unknown as Output;
} else {
clone = { ...entity } as unknown as Output;
}
// Delete prop if `removeIfUndefined` and value is undefined
if (removeIfUndefined && value === undefined && restPath.length === 1) {
delete clone[path][restPath[0]];
} else {
clone[path] = internalSet(clone[path], restPath, value, removeIfUndefined);
}
return clone;
}
export default function set<Entity = any, Output = Entity, Value = any>(
entity: Entity,
paths: (string | number)[],
value: Value,
removeIfUndefined = false,
): Output {
// Do nothing if `removeIfUndefined` and parent object not exist
if (
paths.length &&
removeIfUndefined &&
value === undefined &&
!get(entity, paths.slice(0, -1))
) {
return entity as unknown as Output;
}
return internalSet(entity, paths, value, removeIfUndefined);
}