@@ -1489,4 +1489,87 @@ describe('useForm()', () => {
14891489 form . setValues ( { file : f2 } ) ;
14901490 expect ( form . values . file ) . toEqual ( f2 ) ;
14911491 } ) ;
1492+
1493+ // #5072
1494+ test ( 'preserves dirty meta when field component mounts after programmatic value changes' , async ( ) => {
1495+ let form ! : FormContext < { name : string } > ;
1496+ const showField = ref ( false ) ;
1497+
1498+ mountWithHoc ( {
1499+ setup ( ) {
1500+ form = useForm ( {
1501+ initialValues : { name : '' } ,
1502+ } ) ;
1503+
1504+ return {
1505+ showField,
1506+ } ;
1507+ } ,
1508+ template : `
1509+ <div>
1510+ <template v-if="showField">
1511+ <Field name="name" />
1512+ </template>
1513+ </div>
1514+ ` ,
1515+ } ) ;
1516+
1517+ await flushPromises ( ) ;
1518+
1519+ // Set the field value programmatically before the field component is mounted
1520+ form . setFieldValue ( 'name' , 'John' ) ;
1521+ await flushPromises ( ) ;
1522+
1523+ // Verify the field is dirty before mount
1524+ expect ( form . isFieldDirty ( 'name' ) ) . toBe ( true ) ;
1525+ expect ( form . meta . value . dirty ) . toBe ( true ) ;
1526+
1527+ // Now mount the field component
1528+ showField . value = true ;
1529+ await flushPromises ( ) ;
1530+
1531+ // The dirty state should be preserved after the field component mounts
1532+ expect ( form . values . name ) . toBe ( 'John' ) ;
1533+ expect ( form . isFieldDirty ( 'name' ) ) . toBe ( true ) ;
1534+ expect ( form . meta . value . dirty ) . toBe ( true ) ;
1535+ } ) ;
1536+
1537+ // #5072
1538+ test ( 'preserves touched meta when field component mounts after programmatic changes' , async ( ) => {
1539+ let form ! : FormContext < { name : string } > ;
1540+ const showField = ref ( false ) ;
1541+
1542+ mountWithHoc ( {
1543+ setup ( ) {
1544+ form = useForm ( {
1545+ initialValues : { name : '' } ,
1546+ } ) ;
1547+
1548+ return {
1549+ showField,
1550+ } ;
1551+ } ,
1552+ template : `
1553+ <div>
1554+ <template v-if="showField">
1555+ <Field name="name" />
1556+ </template>
1557+ </div>
1558+ ` ,
1559+ } ) ;
1560+
1561+ await flushPromises ( ) ;
1562+
1563+ // Set the field as touched programmatically before the field component is mounted
1564+ form . setFieldValue ( 'name' , 'John' ) ;
1565+ form . setFieldTouched ( 'name' , true ) ;
1566+ await flushPromises ( ) ;
1567+
1568+ // Now mount the field component
1569+ showField . value = true ;
1570+ await flushPromises ( ) ;
1571+
1572+ // The touched state should be preserved after the field component mounts
1573+ expect ( form . isFieldTouched ( 'name' ) ) . toBe ( true ) ;
1574+ } ) ;
14921575} ) ;
0 commit comments