Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix: ensure to clone user passed values in setters closes #3428
  • Loading branch information
logaretm committed Aug 5, 2021
1 parent cf036ec commit a720c24
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
5 changes: 3 additions & 2 deletions packages/vee-validate/src/useField.ts
Expand Up @@ -13,6 +13,7 @@ import {
nextTick,
} from 'vue';
import { BaseSchema } from 'yup';
import { klona as deepCopy } from 'klona/lite';
import isEqual from 'fast-deep-equal/es6';
import { validate as validateValue } from './validate';
import {
Expand Down Expand Up @@ -404,8 +405,8 @@ function useValidationState<TValue>({
form.setFieldValue(fieldPath, newValue, { force: true });
form.setFieldInitialValue(fieldPath, newValue);
} else {
value.value = newValue;
initialValueRef.value = newValue;
value.value = deepCopy(newValue);
initialValueRef.value = deepCopy(newValue);
}

setErrors(state?.errors || []);
Expand Down
23 changes: 13 additions & 10 deletions packages/vee-validate/src/useForm.ts
Expand Up @@ -192,15 +192,18 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
{ force } = { force: false }
) {
const fieldInstance: RegisteredField | undefined = fieldsById.value[field];
const clonedValue = deepCopy(value);
// field wasn't found, create a virtual field as a placeholder
if (!fieldInstance) {
setInPath(formValues, field as string, value);
setInPath(formValues, field as string, clonedValue);
return;
}

// Multiple checkboxes, and only one of them got updated
if (Array.isArray(fieldInstance) && fieldInstance[0]?.type === 'checkbox' && !Array.isArray(value)) {
const newVal = resolveNextCheckboxValue(getFromPath(formValues, field as string) || [], value, undefined);
const newVal = deepCopy(
resolveNextCheckboxValue(getFromPath(formValues, field as string) || [], value, undefined)
);
setInPath(formValues, field as string, newVal);
fieldInstance.forEach(fieldItem => {
valuesByFid[fieldItem.fid] = newVal;
Expand All @@ -211,10 +214,12 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
let newValue = value;
// Single Checkbox: toggles the field value unless the field is being reset then force it
if (!Array.isArray(fieldInstance) && fieldInstance?.type === 'checkbox' && !force) {
newValue = resolveNextCheckboxValue<TValues[T]>(
getFromPath<TValues[T]>(formValues, field as string) as TValues[T],
value as TValues[T],
unref(fieldInstance.uncheckedValue) as TValues[T]
newValue = deepCopy(
resolveNextCheckboxValue<TValues[T]>(
getFromPath<TValues[T]>(formValues, field as string) as TValues[T],
value as TValues[T],
unref(fieldInstance.uncheckedValue) as TValues[T]
)
);
}

Expand Down Expand Up @@ -492,7 +497,7 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
}

function setFieldInitialValue(path: string, value: unknown) {
setInPath(initialValues.value, path, value);
setInPath(initialValues.value, path, deepCopy(value));
}

/**
Expand Down Expand Up @@ -679,9 +684,7 @@ function useFormInitialValues<TValues extends Record<string, any>>(
});

function setInitialValues(values: Partial<TValues>, updateFields = false) {
initialValues.value = {
...values,
};
initialValues.value = deepCopy(values);

if (!updateFields) {
return;
Expand Down

0 comments on commit a720c24

Please sign in to comment.