diff --git a/packages/vee-validate/src/useForm.ts b/packages/vee-validate/src/useForm.ts index 86ee30550..aebdcbbcb 100644 --- a/packages/vee-validate/src/useForm.ts +++ b/packages/vee-validate/src/useForm.ts @@ -269,8 +269,15 @@ export function useForm = Record { + (newPath, oldPath) => { setFieldValue(newPath, valuesByFid[field.fid]); + const isSharingName = fields.value.find(f => unref(f.name) === oldPath); + // clean up the old path if no other field is sharing that name + // #3325 + if (!isSharingName) { + unsetPath(formValues, oldPath); + unsetPath(initialValues.value, oldPath); + } }, { flush: 'post', @@ -296,6 +303,7 @@ export function useForm = Record unref(f.name) === fieldName); if (isSharingName) { diff --git a/packages/vee-validate/tests/Form.spec.ts b/packages/vee-validate/tests/Form.spec.ts index 8239c4013..f9bd18340 100644 --- a/packages/vee-validate/tests/Form.spec.ts +++ b/packages/vee-validate/tests/Form.spec.ts @@ -1988,4 +1988,61 @@ describe('
', () => { expect(passwordError.textContent).toBe(errorMessage); expect(passwordValue.textContent).toBe(value); }); + + // #3325 + test('unsets old path value when array fields are removed', async () => { + const onSubmit = jest.fn(); + mountWithHoc({ + setup() { + const users = ref([ + { id: 1, name: '111' }, + { id: 2, name: '222' }, + { id: 3, name: '333' }, + ]); + + function remove(idx: number) { + users.value.splice(idx, 1); + } + + return { + onSubmit, + users, + remove, + }; + }, + template: ` + +
+ User #{{ idx }} + + + + + +
+ + +
+ `, + }); + + await flushPromises(); + const submitBtn = document.querySelector('.submit') as HTMLButtonElement; + const inputs = Array.from(document.querySelectorAll('input')) as HTMLInputElement[]; + const removeBtn = document.querySelectorAll('.remove')[1] as HTMLButtonElement; // remove the second item + setValue(inputs[0], '111'); + setValue(inputs[1], '222'); + setValue(inputs[2], '333'); + await flushPromises(); + removeBtn.click(); + await flushPromises(); + (submitBtn as HTMLButtonElement).click(); + await flushPromises(); + expect(onSubmit).toHaveBeenCalledWith( + expect.objectContaining({ + users: [{ name: '111' }, { name: '333' }], + }), + expect.anything() + ); + }); });