@@ -295,6 +295,7 @@ export class FormApi {
295
295
return true ;
296
296
} ) ;
297
297
const filteredFields = fieldMergeFn ( fields , form . values ) ;
298
+ this . handleStringToArrayFields ( filteredFields ) ;
298
299
form . setValues ( filteredFields , shouldValidate ) ;
299
300
}
300
301
@@ -304,6 +305,7 @@ export class FormApi {
304
305
const form = await this . getForm ( ) ;
305
306
await form . submitForm ( ) ;
306
307
const rawValues = toRaw ( await this . getValues ( ) ) ;
308
+ this . handleArrayToStringFields ( rawValues ) ;
307
309
await this . state ?. handleSubmit ?.( rawValues ) ;
308
310
309
311
return rawValues ;
@@ -392,10 +394,53 @@ export class FormApi {
392
394
return this . form ;
393
395
}
394
396
397
+ private handleArrayToStringFields = ( originValues : Record < string , any > ) => {
398
+ const arrayToStringFields = this . state ?. arrayToStringFields ;
399
+ if ( ! arrayToStringFields || ! Array . isArray ( arrayToStringFields ) ) {
400
+ return ;
401
+ }
402
+
403
+ const processFields = ( fields : string [ ] , separator : string = ',' ) => {
404
+ this . processFields ( fields , separator , originValues , ( value , sep ) =>
405
+ Array . isArray ( value ) ? value . join ( sep ) : value ,
406
+ ) ;
407
+ } ;
408
+
409
+ // 处理简单数组格式 ['field1', 'field2', ';'] 或 ['field1', 'field2']
410
+ if ( arrayToStringFields . every ( ( item ) => typeof item === 'string' ) ) {
411
+ const lastItem =
412
+ arrayToStringFields [ arrayToStringFields . length - 1 ] || '' ;
413
+ const fields =
414
+ lastItem . length === 1
415
+ ? arrayToStringFields . slice ( 0 , - 1 )
416
+ : arrayToStringFields ;
417
+ const separator = lastItem . length === 1 ? lastItem : ',' ;
418
+ processFields ( fields , separator ) ;
419
+ return ;
420
+ }
421
+
422
+ // 处理嵌套数组格式 [['field1'], ';']
423
+ arrayToStringFields . forEach ( ( fieldConfig ) => {
424
+ if ( Array . isArray ( fieldConfig ) ) {
425
+ const [ fields , separator = ',' ] = fieldConfig ;
426
+ // 根据类型定义,fields 应该始终是字符串数组
427
+ if ( ! Array . isArray ( fields ) ) {
428
+ console . warn (
429
+ `Invalid field configuration: fields should be an array of strings, got ${ typeof fields } ` ,
430
+ ) ;
431
+ return ;
432
+ }
433
+ processFields ( fields , separator ) ;
434
+ }
435
+ } ) ;
436
+ } ;
437
+
395
438
private handleRangeTimeValue = ( originValues : Record < string , any > ) => {
396
439
const values = { ...originValues } ;
397
440
const fieldMappingTime = this . state ?. fieldMappingTime ;
398
441
442
+ this . handleStringToArrayFields ( values ) ;
443
+
399
444
if ( ! fieldMappingTime || ! Array . isArray ( fieldMappingTime ) ) {
400
445
return values ;
401
446
}
@@ -441,6 +486,80 @@ export class FormApi {
441
486
return values ;
442
487
} ;
443
488
489
+ private handleStringToArrayFields = ( originValues : Record < string , any > ) => {
490
+ const arrayToStringFields = this . state ?. arrayToStringFields ;
491
+ if ( ! arrayToStringFields || ! Array . isArray ( arrayToStringFields ) ) {
492
+ return ;
493
+ }
494
+
495
+ const processFields = ( fields : string [ ] , separator : string = ',' ) => {
496
+ this . processFields ( fields , separator , originValues , ( value , sep ) => {
497
+ if ( typeof value !== 'string' ) {
498
+ return value ;
499
+ }
500
+ // 处理空字符串的情况
501
+ if ( value === '' ) {
502
+ return [ ] ;
503
+ }
504
+ // 处理复杂分隔符的情况
505
+ const escapedSeparator = sep . replaceAll (
506
+ / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g,
507
+ String . raw `\$&` ,
508
+ ) ;
509
+ return value . split ( new RegExp ( escapedSeparator ) ) ;
510
+ } ) ;
511
+ } ;
512
+
513
+ // 处理简单数组格式 ['field1', 'field2', ';'] 或 ['field1', 'field2']
514
+ if ( arrayToStringFields . every ( ( item ) => typeof item === 'string' ) ) {
515
+ const lastItem =
516
+ arrayToStringFields [ arrayToStringFields . length - 1 ] || '' ;
517
+ const fields =
518
+ lastItem . length === 1
519
+ ? arrayToStringFields . slice ( 0 , - 1 )
520
+ : arrayToStringFields ;
521
+ const separator = lastItem . length === 1 ? lastItem : ',' ;
522
+ processFields ( fields , separator ) ;
523
+ return ;
524
+ }
525
+
526
+ // 处理嵌套数组格式 [['field1'], ';']
527
+ arrayToStringFields . forEach ( ( fieldConfig ) => {
528
+ if ( Array . isArray ( fieldConfig ) ) {
529
+ const [ fields , separator = ',' ] = fieldConfig ;
530
+ if ( Array . isArray ( fields ) ) {
531
+ processFields ( fields , separator ) ;
532
+ } else if ( typeof originValues [ fields ] === 'string' ) {
533
+ const value = originValues [ fields ] ;
534
+ if ( value === '' ) {
535
+ originValues [ fields ] = [ ] ;
536
+ } else {
537
+ const escapedSeparator = separator . replaceAll (
538
+ / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g,
539
+ String . raw `\$&` ,
540
+ ) ;
541
+ originValues [ fields ] = value . split ( new RegExp ( escapedSeparator ) ) ;
542
+ }
543
+ }
544
+ }
545
+ } ) ;
546
+ } ;
547
+
548
+ private processFields = (
549
+ fields : string [ ] ,
550
+ separator : string ,
551
+ originValues : Record < string , any > ,
552
+ transformFn : ( value : any , separator : string ) => any ,
553
+ ) => {
554
+ fields . forEach ( ( field ) => {
555
+ const value = originValues [ field ] ;
556
+ if ( value === undefined || value === null ) {
557
+ return ;
558
+ }
559
+ originValues [ field ] = transformFn ( value , separator ) ;
560
+ } ) ;
561
+ } ;
562
+
444
563
private updateState ( ) {
445
564
const currentSchema = this . state ?. schema ?? [ ] ;
446
565
const prevSchema = this . prevState ?. schema ?? [ ] ;
0 commit comments