From d3f0fc094c89375bd67bdd3f533e5ab545a83611 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Sat, 11 Sep 2021 02:25:23 +0200 Subject: [PATCH] fix: dynamic rule forcing validation closes #3485 --- packages/vee-validate/src/useField.ts | 4 +-- packages/vee-validate/tests/Field.spec.ts | 36 ++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/vee-validate/src/useField.ts b/packages/vee-validate/src/useField.ts index 8b5d0f40f..c85247d46 100644 --- a/packages/vee-validate/src/useField.ts +++ b/packages/vee-validate/src/useField.ts @@ -237,7 +237,7 @@ export function useField( return; } - return validateWithStateMutation(); + meta.validated ? validateWithStateMutation() : validateValidStateOnly(); }, { deep: true, @@ -293,7 +293,7 @@ export function useField( const shouldValidate = !isEqual(deps, oldDeps); if (shouldValidate) { - meta.dirty ? validateWithStateMutation() : validateValidStateOnly(); + meta.validated ? validateWithStateMutation() : validateValidStateOnly(); } }); diff --git a/packages/vee-validate/tests/Field.spec.ts b/packages/vee-validate/tests/Field.spec.ts index 969975afe..67215e42a 100644 --- a/packages/vee-validate/tests/Field.spec.ts +++ b/packages/vee-validate/tests/Field.spec.ts @@ -2,7 +2,7 @@ import flushPromises from 'flush-promises'; import { defineRule, configure } from '@/vee-validate'; import { mountWithHoc, setValue, dispatchEvent, setChecked } from './helpers'; import * as yup from 'yup'; -import { reactive, ref, Ref } from 'vue'; +import { computed, reactive, ref, Ref } from 'vue'; jest.useFakeTimers(); @@ -1062,4 +1062,38 @@ describe('', () => { await flushPromises(); expect(input.value).toBe(''); }); + + // #3485 + test('computed rules should not generate errors unless the field was validated before', async () => { + const isRequired = ref(false); + const rules = computed(() => (isRequired.value ? 'required' : '')); + mountWithHoc({ + setup() { + return { + rules, + }; + }, + template: ` + + + {{ errorMessage }} + + `, + }); + + await flushPromises(); + const input = document.querySelector('input') as HTMLInputElement; + const error = document.querySelector('span') as HTMLInputElement; + isRequired.value = true; + await flushPromises(); + expect(error.textContent).toBe(''); + isRequired.value = false; + await flushPromises(); + expect(error.textContent).toBe(''); + setValue(input, ''); + await flushPromises(); + isRequired.value = true; + await flushPromises(); + expect(error.textContent).toBe(REQUIRED_MESSAGE); + }); });