@@ -3241,3 +3241,76 @@ test('handles onSubmit with generic object from zod schema', async () => {
32413241 expect . anything ( ) ,
32423242 ) ;
32433243} ) ;
3244+
3245+ // #5050
3246+ test ( 'setFieldValue from Form slot should not trigger validation when Field validateOnChange is false' , async ( ) => {
3247+ const REQUIRED_MSG = 'This field is required' ;
3248+ defineRule ( 'required_5050' , ( value : unknown ) => {
3249+ if ( ! value ) {
3250+ return REQUIRED_MSG ;
3251+ }
3252+ return true ;
3253+ } ) ;
3254+
3255+ const wrapper = mountWithHoc ( {
3256+ template : `
3257+ <VForm v-slot="{ setFieldValue, errors }">
3258+ <Field name="field" rules="required_5050" :validateOnChange="false" :validateOnInput="false" :validateOnBlur="false" :validateOnModelUpdate="false" />
3259+ <span id="error">{{ errors.field }}</span>
3260+ <button type="button" @click="setFieldValue('field', '')">Set empty</button>
3261+ </VForm>
3262+ ` ,
3263+ } ) ;
3264+
3265+ await flushPromises ( ) ;
3266+ const error = wrapper . $el . querySelector ( '#error' ) ;
3267+ expect ( error . textContent ) . toBe ( '' ) ;
3268+
3269+ // Click the button to set the field value to empty string via setFieldValue
3270+ wrapper . $el . querySelector ( 'button' ) . click ( ) ;
3271+ await flushPromises ( ) ;
3272+
3273+ // Should NOT show validation error because validateOnChange/Input/Blur/ModelUpdate are all false
3274+ expect ( error . textContent ) . toBe ( '' ) ;
3275+ } ) ;
3276+
3277+ // #5050
3278+ test ( 'setFieldValue should still trigger validation on previously validated fields' , async ( ) => {
3279+ const REQUIRED_MSG = 'This field is required' ;
3280+ defineRule ( 'required_5050b' , ( value : unknown ) => {
3281+ if ( ! value ) {
3282+ return REQUIRED_MSG ;
3283+ }
3284+ return true ;
3285+ } ) ;
3286+
3287+ const wrapper = mountWithHoc ( {
3288+ template : `
3289+ <VForm v-slot="{ setFieldValue, errors }" @submit="() => {}">
3290+ <Field name="field" rules="required_5050b" :validateOnChange="false" :validateOnInput="false" :validateOnBlur="false" :validateOnModelUpdate="false" />
3291+ <span id="error">{{ errors.field }}</span>
3292+ <button id="submit" type="submit">Submit</button>
3293+ <button id="setEmpty" type="button" @click="setFieldValue('field', '')">Set empty</button>
3294+ </VForm>
3295+ ` ,
3296+ } ) ;
3297+
3298+ await flushPromises ( ) ;
3299+ const error = wrapper . $el . querySelector ( '#error' ) ;
3300+ expect ( error . textContent ) . toBe ( '' ) ;
3301+
3302+ // Submit the form to trigger validation (marks fields as validated)
3303+ wrapper . $el . querySelector ( '#submit' ) . click ( ) ;
3304+ await flushPromises ( ) ;
3305+
3306+ // After submit, the field should show the error since it's empty and required
3307+ expect ( error . textContent ) . toBe ( REQUIRED_MSG ) ;
3308+
3309+ // Set value to empty again via setFieldValue
3310+ wrapper . $el . querySelector ( '#setEmpty' ) . click ( ) ;
3311+ await flushPromises ( ) ;
3312+
3313+ // After setFieldValue on a previously validated field, validation should still update
3314+ // The field is already validated so setFieldValue should re-validate
3315+ expect ( error . textContent ) . toBe ( REQUIRED_MSG ) ;
3316+ } ) ;
0 commit comments