8000 :sparkles: make sure when using append, prepend, insert can use defau… · vue-use-form/vue-use-form@b59f6e5 · GitHub
[go: up one dir, main page]

Skip to content

Commit b59f6e5

Browse files
committed
✨ make sure when using append, prepend, insert can use defaultValue
1 parent 50717dc commit b59f6e5

File tree

4 files changed

+58
-55
lines changed

4 files changed

+58
-55
lines changed

packages/core/src/logic/creatFormControl.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { nextTick, reactive, ref, unref } from 'vue'
2-
32
import { VALIDATION_MODE } from '../shared/constant'
43
import type { FieldError, FieldErrors } from '../types/errors'
54
import type { Field, FieldElement, FieldValues, Fields } from '../types/filed'
@@ -24,7 +23,7 @@ import type {
2423
UseFormUnregister,
2524
} from '../types/form'
2625
import type { DefaultValues, UnpackNestedValue } from '../types/utils'
27-
import { get, isArray, isEmptyObject, isFunction, isNullOrUndefined, isString, isUndefined, set, unset } from '../utils'
26+
import { get, isArray, isEmptyObject, isFunction, isNullOrUndefined, isNumber, isString, isUndefined, set, unset } from '../utils'
2827

2928
import {
3029
createErrorHandler as createErrorHandlerUtil,
@@ -60,6 +59,7 @@ export function creatFormControl<TFieldValues extends FieldValues = FieldValues>
6059
}) as FormState<TFieldValues>
6160

6261
const _defaultValues = _options.defaultValues || {} as DefaultValues<TFieldValues>
62+
const _fieldArrayDefaultValues = {} as DefaultValues<TFieldValues>
6363

6464
const validationModeBeforeSubmit = getValidationMode(_options.mode!)
6565
const shouldDisplayAllAssociatedErrors
@@ -377,7 +377,10 @@ export function creatFormControl<TFieldValues extends FieldValues = FieldValues>
377377
let isModelValue = false
378378
let field = get(_fields, fieldName)
379379

380-
const defaultVal = options?.value || get(_defaultValues, fieldName as string) || ''
380+
const defaultVal = options?.value
381+
|| get(_defaultValues, fieldName as string)
382+
|| get(_fieldArrayDefaultValues, (fieldName as string).split('.').find(item => isNumber(parseInt(item))))
383+
|| ''
381384

382385
if (!field) {
383386
_setFields(fieldName, {
@@ -431,7 +434,7 @@ export function creatFormControl<TFieldValues extends FieldValues = FieldValues>
431434
...(!isFieldElement(field.el) && { ref: _fields[fieldName].el }),
432435

433436
value: field.inputValue.value,
434-
onInput: async (e: InputEvent) => {
437+
onInput: (e: InputEvent) => {
435438
if (_fields[fieldName].isUnregistered) {
436439
return
437440
}
@@ -447,14 +450,14 @@ export function creatFormControl<TFieldValues extends FieldValues = FieldValues>
447450
},
448451

449452
'modelValue': field.inputValue.value,
450-
'onUpdate:modelValue': async (input: any) => {
453+
'onUpdate:modelValue': (input: any) => {
451454
if (_fields[fieldName].isUnregistered) {
452455
return
453456
}
454457

455458
isModelValue = true
456459
addEventListenerToElement()
457-
await handleValueChange(input)
460+
handleValueChange(input)
458461
},
459462
}
460463
}
@@ -488,6 +491,7 @@ export function creatFormControl<TFieldValues extends FieldValues = FieldValues>
488491
control: {
489492
_fields,
490493
_formState,
494+
_fieldArrayDefaultValues,
491495
handleSubmit,
492496
createErrorHandler,
493497
createSubmitHandler,

packages/core/src/logic/createFieldArray.ts

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { reactive } from 'vue'
22
import type {
3-
ArrayFieldRegisterOptions,
43
UseFieldArrayAppend,
54
UseFieldArrayField,
65
UseFieldArrayInsert,
@@ -10,57 +9,64 @@ import type {
109
UseFieldArraySwap,
1110
} from '../types/fieldArray'
1211
import type { FieldValues } from '../types/filed'
13-
import type { IsString } from '../types/utils'
14-
import { isArray } from '../utils'
12+
import { isArray, set } from '../utils'
1513

1614
export function createFieldArray<TFieldsValues extends FieldValues = FieldValues>(
1715
_options: UseFieldArrayProps<TFieldsValues>,
1816
) {
1917
type TFields = UseFieldArrayField<TFieldsValues>
18+
type TArrayField = TFieldsValues[typeof name] extends [infer R] ? R extends FieldValues ? R[] : FieldValues[] : FieldValues[]
2019

21-
const { control } = _options
22-
23-
const { register } = control
20+
const { name, control } = _options
2421

2522
const _fields = reactive([]) as TFields[]
2623

27-
const _createFields = (fieldName: string, options: Partial<ArrayFieldRegisterOptions<TFieldsValues, IsString<keyof TFieldsValues>>> = {}) => {
28-
const registeredItem = register(fieldName, options)
24+
let fieldIndex = 0
25+
26+
const _createFields = (
27+
fieldName: string,
28+
defaultVal: unknown,
29+
) => {
30+
let index = fieldIndex
31+
fieldIndex++
32+
33+
set(control._fieldArrayDefaultValues, index, defaultVal)
2934

3035
return {
31-
index: _fields.length,
36+
index,
3237
name: fieldName,
33-
model: registeredItem[0],
34-
ref: registeredItem[1],
35-
type: options.type || 'text',
3638
} as TFields
3739
}
3840

39-
const append: UseFieldArrayAppend<TFieldsValues> = (fields) => {
40-
Object.entries(fields).forEach(([fieldName, options]) => {
41-
_fields.push(_createFields(fieldName, options))
41+
const append: UseFieldArrayAppend<TArrayField> = (fields) => {
42+
Object.entries(fields).forEach(([fieldName, defaultVal]) => {
43+
_fields.push(_createFields(fieldName, defaultVal))
4244
})
4345
}
4446

45-
const prepend: UseFieldArrayPrepend<TFieldsValues> = (fields) => {
46-
Object.entries(fields).forEach(([fieldName, options]) => {
47-
_fields.unshift(_createFields(fieldName, options))
47+
const prepend: UseFieldArrayPrepend<TArrayField> = (fields) => {
48+
Object.entries(fields).forEach(([fieldName, defaultVal]) => {
49+
_fields.unshift(_createFields(fieldName, defaultVal))
4850
})
4951
}
5052

51-
const remove: UseFieldArrayRemove = (index) => {
52-
if (!isArray(index)) {
53-
index = [index]
53+
const remove: UseFieldArrayRemove = (indexes) => {
54+
if (!isArray(indexes)) {
55+
indexes = [indexes]
56+
}
57+
for (const index of indexes) {
58+
const targetIndex = _fields.findIndex(field => field.index === index)
59+
60+
if (targetIndex >= 0) {
61+
_fields.splice(targetIndex, 1)
62+
}
5463
}
55-
index.forEach((item, index) => {
56-
_fields.splice(item - index, 1)
57-
})
5864
}
5965

60-
const insert: UseFieldArrayInsert<TFieldsValues> = (startIndex, fields) => {
61-
Object.entries(fields).forEach(([fieldName, options], index) => {
62-
_fields.splice(startIndex + index, 0, _createFields(fieldName, options))
63-
})
66+
const insert: UseFieldArrayInsert<TArrayField> = (startIndex, fields) => {
67+
const fieldsMap = Object.entries(fields).map(([fieldName, options]) => _createFields(fieldName, options))
68+
69+
_fields.splice(startIndex, 0, ...fieldsMap)
6470
}
6571

6672
const swap: UseFieldArraySwap = (from, to) => {

packages/core/src/types/fieldArray.ts

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import type { FieldValues } from './filed'
22
import type { UseFormControl } from './form'
3-
import type { IsString } from './utils'
4-
import type { RegisterOptions } from './validator'
5-
6-
export type ArrayFieldRegisterOptions<
7-
TFieldValues extends FieldValues = FieldValues,
8-
FieldNames extends string = IsString<keyof TFieldValues>,
9-
> = RegisterOptions<TFieldValues, FieldNames> & { type: string }
103

114
export interface UseFieldArrayField<
125
TFieldValues extends FieldValues = FieldValues,
@@ -15,35 +8,33 @@ export interface UseFieldArrayField<
158
name: keyof TFieldValues
169
}
1710

18-
export interface UseFieldArrayProps<FieldValues> {
19-
control: UseFormControl<FieldValues>
11+
export interface UseFieldArrayProps<TFieldValues extends FieldValues> {
12+
control: UseFormControl<TFieldValues>
13+
name: keyof TFieldValues
2014
}
2115

2216
export type FieldPayload<
23-
TFieldValues extends FieldValues = FieldValues,
24-
FieldNames extends string = IsString<keyof TFieldValues>,
17+
TFieldValues extends FieldValues[] = FieldValues[],
18+
FieldNames extends string = TFieldValues extends (infer R)[] ? keyof R : '',
2519
> = {
26-
[K in FieldNames]?: ArrayFieldRegisterOptions<TFieldValues, FieldNames>
20+
[K in FieldNames]?: TFieldValues extends (infer R)[] ? R[keyof R]: never
2721
}
2822

29-
export type UseFieldArrayInsert<FieldValues> = (startIndex: number, field: FieldPayload<FieldValues>) => void
23+
export type UseFieldArrayInsert<TFieldValues extends FieldValues[]> = (startIndex: number, field: FieldPayload<TFieldValues>) => void
3024

31-
export type UseFieldArrayAppend<FieldValues> = (obj: FieldPayload<FieldValues>) => void
25+
export type UseFieldArrayAppend<TFieldValues extends FieldValues[]> = (field: FieldPayload<TFieldValues>) => void
3226

33-
export type UseFieldArrayPrepend<FieldValues> = (obj: FieldPayload<FieldValues>) => void
27+
export type UseFieldArrayPrepend<TFieldValues extends FieldValues[]> = (field: FieldPayload<TFieldValues>) => void
3428

3529
export type UseFieldArrayRemove = (id: number | number[]) => void
3630

37-
export type UseFieldArrayMove = (from: number, to: number) => void
38-
3931
export type UseFieldArraySwap = (from: number, to: number) => void
4032

4133
export interface UseFieldArrayReturn<FieldValues> {
42-
move: UseFieldArrayMove
43-
insert: UseFieldArrayInsert<FieldValues>
34+
insert: UseFieldArrayInsert<FieldValues[]>
4435
remove: UseFieldArrayRemove
45-
prepend: UseFieldArrayPrepend<FieldValues>
46-
append: UseFieldArrayAppend<FieldValues>
36+
prepend: UseFieldArrayPrepend<FieldValues[]>
37+
append: UseFieldArrayAppend<FieldValues[]>
4738
swap: UseFieldArraySwap
4839
fields: UseFieldArrayField<FieldValues>[]
4940
}

packages/core/src/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export const isFunction = (val: unknown): val is Function =>
22
typeof val === 'function'
33

4+
export const isNumber = (val: unknown): val is number => typeof val === 'number' && !isNaN(val)
5+
46
export const isString = (val: unknown): val is string => typeof val === 'string'
57

68
export const isBoolean = (val: unknown): val is Boolean => typeof val === 'boolean'

0 commit comments

Comments
 (0)
0