vee-validate 4.5.4 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -24
- package/dist/vee-validate.d.ts +548 -293
- package/dist/vee-validate.esm.js +265 -110
- package/dist/vee-validate.js +261 -108
- package/dist/vee-validate.min.js +3 -3
- package/package.json +3 -3
- package/CHANGELOG.md +0 -830
package/dist/vee-validate.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vee-validate v4.
|
|
3
|
-
* (c)
|
|
2
|
+
* vee-validate v4.6.0
|
|
3
|
+
* (c) 2022 Abdelrahman Awad
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
|
-
import { inject, getCurrentInstance, warn as warn$1, ref, unref, computed, reactive, watch, onUnmounted, nextTick, onMounted, provide, isRef, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h,
|
|
6
|
+
import { inject, getCurrentInstance, warn as warn$1, ref, unref, computed, reactive, watch, onUnmounted, nextTick, onMounted, provide, isRef, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, watchEffect, markRaw } from 'vue';
|
|
7
7
|
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
|
8
8
|
|
|
9
9
|
function isCallable(fn) {
|
|
@@ -53,18 +53,6 @@ const IS_ABSENT = Symbol('Default empty value');
|
|
|
53
53
|
function isLocator(value) {
|
|
54
54
|
return isCallable(value) && !!value.__locatorRef;
|
|
55
55
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Checks if an tag name is a native HTML tag and not a Vue component
|
|
58
|
-
*/
|
|
59
|
-
function isHTMLTag(tag) {
|
|
60
|
-
return ['input', 'textarea', 'select'].includes(tag);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Checks if an input is of type file
|
|
64
|
-
*/
|
|
65
|
-
function isFileInputNode(tag, attrs) {
|
|
66
|
-
return isHTMLTag(tag) && attrs.type === 'file';
|
|
67
|
-
}
|
|
68
56
|
function isYupValidator(value) {
|
|
69
57
|
return !!value && isCallable(value.validate);
|
|
70
58
|
}
|
|
@@ -117,7 +105,7 @@ function isNativeMultiSelectNode(tag, attrs) {
|
|
|
117
105
|
* For multi-selects because the value binding will reset the value
|
|
118
106
|
*/
|
|
119
107
|
function shouldHaveValueBinding(tag, attrs) {
|
|
120
|
-
return isNativeMultiSelectNode(tag, attrs)
|
|
108
|
+
return !isNativeMultiSelectNode(tag, attrs) && attrs.type !== 'file' && !hasCheckedAttr(attrs.type);
|
|
121
109
|
}
|
|
122
110
|
function isFormSubmitEvent(evt) {
|
|
123
111
|
return isEvent(evt) && evt.target && 'submit' in evt.target;
|
|
@@ -301,6 +289,15 @@ function debounceAsync(inner, ms = 0) {
|
|
|
301
289
|
}, ms);
|
|
302
290
|
return new Promise(resolve => resolves.push(resolve));
|
|
303
291
|
};
|
|
292
|
+
}
|
|
293
|
+
function applyModelModifiers(value, modifiers) {
|
|
294
|
+
if (!isObject(modifiers)) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (modifiers.number) {
|
|
298
|
+
return toNumber(value);
|
|
299
|
+
}
|
|
300
|
+
return value;
|
|
304
301
|
}
|
|
305
302
|
|
|
306
303
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -344,7 +341,8 @@ function normalizeEventValue(value) {
|
|
|
344
341
|
return getBoundValue(input);
|
|
345
342
|
}
|
|
346
343
|
if (input.type === 'file' && input.files) {
|
|
347
|
-
|
|
344
|
+
const files = Array.from(input.files);
|
|
345
|
+
return input.multiple ? files : files[0];
|
|
348
346
|
}
|
|
349
347
|
if (isNativeMultiSelect(input)) {
|
|
350
348
|
return Array.from(input.options)
|
|
@@ -503,18 +501,34 @@ async function _validate(field, value) {
|
|
|
503
501
|
if (isYupValidator(field.rules)) {
|
|
504
502
|
return validateFieldWithYup(value, field.rules, { bails: field.bails });
|
|
505
503
|
}
|
|
506
|
-
// if a generic function
|
|
507
|
-
if (isCallable(field.rules)) {
|
|
504
|
+
// if a generic function or chain of generic functions
|
|
505
|
+
if (isCallable(field.rules) || Array.isArray(field.rules)) {
|
|
508
506
|
const ctx = {
|
|
509
507
|
field: field.name,
|
|
510
508
|
form: field.formData,
|
|
511
509
|
value: value,
|
|
512
510
|
};
|
|
513
|
-
|
|
514
|
-
const
|
|
515
|
-
const
|
|
511
|
+
// Normalize the pipeline
|
|
512
|
+
const pipeline = Array.isArray(field.rules) ? field.rules : [field.rules];
|
|
513
|
+
const length = pipeline.length;
|
|
514
|
+
const errors = [];
|
|
515
|
+
for (let i = 0; i < length; i++) {
|
|
516
|
+
const rule = pipeline[i];
|
|
517
|
+
const result = await rule(value, ctx);
|
|
518
|
+
const isValid = typeof result !== 'string' && result;
|
|
519
|
+
if (isValid) {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const message = typeof result === 'string' ? result : _generateFieldError(ctx);
|
|
523
|
+
errors.push(message);
|
|
524
|
+
if (field.bails) {
|
|
525
|
+
return {
|
|
526
|
+
errors,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
}
|
|
516
530
|
return {
|
|
517
|
-
errors
|
|
531
|
+
errors,
|
|
518
532
|
};
|
|
519
533
|
}
|
|
520
534
|
const normalizedContext = Object.assign(Object.assign({}, field), { rules: normalizeRules(field.rules) });
|
|
@@ -827,8 +841,8 @@ function useFieldState(path, init) {
|
|
|
827
841
|
/**
|
|
828
842
|
* Creates the field value and resolves the initial value
|
|
829
843
|
*/
|
|
830
|
-
function _useFieldValue(path, modelValue, shouldInjectForm) {
|
|
831
|
-
const form = shouldInjectForm ? injectWithSelf(FormContextKey, undefined) : undefined;
|
|
844
|
+
function _useFieldValue(path, modelValue, shouldInjectForm = true) {
|
|
845
|
+
const form = shouldInjectForm === true ? injectWithSelf(FormContextKey, undefined) : undefined;
|
|
832
846
|
const modelRef = ref(unref(modelValue));
|
|
833
847
|
function resolveInitialValue() {
|
|
834
848
|
if (!form) {
|
|
@@ -858,7 +872,7 @@ function _useFieldValue(path, modelValue, shouldInjectForm) {
|
|
|
858
872
|
// prioritize model value over form values
|
|
859
873
|
// #3429
|
|
860
874
|
const currentValue = modelValue ? unref(modelValue) : getFromPath(form.values, unref(path), unref(initialValue));
|
|
861
|
-
form.stageInitialValue(unref(path), currentValue);
|
|
875
|
+
form.stageInitialValue(unref(path), currentValue, true);
|
|
862
876
|
// otherwise use a computed setter that triggers the `setFieldValue`
|
|
863
877
|
const value = computed({
|
|
864
878
|
get() {
|
|
@@ -1297,12 +1311,17 @@ function useField(name, rules, opts) {
|
|
|
1297
1311
|
return _useField(name, rules, opts);
|
|
1298
1312
|
}
|
|
1299
1313
|
function _useField(name, rules, opts) {
|
|
1300
|
-
const { initialValue: modelValue, validateOnMount, bails, type, checkedValue, label, validateOnValueUpdate, uncheckedValue, standalone, } = normalizeOptions(unref(name), opts);
|
|
1314
|
+
const { initialValue: modelValue, validateOnMount, bails, type, checkedValue, label, validateOnValueUpdate, uncheckedValue, standalone, keepValueOnUnmount, modelPropName, syncVModel, } = normalizeOptions(unref(name), opts);
|
|
1301
1315
|
const form = !standalone ? injectWithSelf(FormContextKey) : undefined;
|
|
1316
|
+
// a flag indicating if the field is about to be removed/unmounted.
|
|
1317
|
+
let markedForRemoval = false;
|
|
1302
1318
|
const { id, value, initialValue, meta, setState, errors, errorMessage } = useFieldState(name, {
|
|
1303
1319
|
modelValue,
|
|
1304
1320
|
standalone,
|
|
1305
1321
|
});
|
|
1322
|
+
if (syncVModel) {
|
|
1323
|
+
useVModel({ value, prop: modelPropName, handleChange });
|
|
1324
|
+
}
|
|
1306
1325
|
/**
|
|
1307
1326
|
* Handles common onBlur meta update
|
|
1308
1327
|
*/
|
|
@@ -1315,7 +1334,7 @@ function _useField(name, rules, opts) {
|
|
|
1315
1334
|
if (schema && !isYupValidator(schema)) {
|
|
1316
1335
|
rulesValue = extractRuleFromSchema(schema, unref(name)) || rulesValue;
|
|
1317
1336
|
}
|
|
1318
|
-
if (isYupValidator(rulesValue) || isCallable(rulesValue)) {
|
|
1337
|
+
if (isYupValidator(rulesValue) || isCallable(rulesValue) || Array.isArray(rulesValue)) {
|
|
1319
1338
|
return rulesValue;
|
|
1320
1339
|
}
|
|
1321
1340
|
return normalizeRules(rulesValue);
|
|
@@ -1335,12 +1354,19 @@ function _useField(name, rules, opts) {
|
|
|
1335
1354
|
meta.pending = true;
|
|
1336
1355
|
meta.validated = true;
|
|
1337
1356
|
const result = await validateCurrentValue('validated-only');
|
|
1357
|
+
if (markedForRemoval) {
|
|
1358
|
+
result.valid = true;
|
|
1359
|
+
result.errors = [];
|
|
1360
|
+
}
|
|
1338
1361
|
setState({ errors: result.errors });
|
|
1339
1362
|
meta.pending = false;
|
|
1340
1363
|
return result;
|
|
1341
1364
|
}
|
|
1342
1365
|
async function validateValidStateOnly() {
|
|
1343
1366
|
const result = await validateCurrentValue('silent');
|
|
1367
|
+
if (markedForRemoval) {
|
|
1368
|
+
result.valid = true;
|
|
1369
|
+
}
|
|
1344
1370
|
meta.valid = result.valid;
|
|
1345
1371
|
return result;
|
|
1346
1372
|
}
|
|
@@ -1354,13 +1380,13 @@ function _useField(name, rules, opts) {
|
|
|
1354
1380
|
return validateValidStateOnly();
|
|
1355
1381
|
}
|
|
1356
1382
|
// Common input/change event handler
|
|
1357
|
-
|
|
1383
|
+
function handleChange(e, shouldValidate = true) {
|
|
1358
1384
|
const newValue = normalizeEventValue(e);
|
|
1359
1385
|
value.value = newValue;
|
|
1360
1386
|
if (!validateOnValueUpdate && shouldValidate) {
|
|
1361
1387
|
validateWithStateMutation();
|
|
1362
1388
|
}
|
|
1363
|
-
}
|
|
1389
|
+
}
|
|
1364
1390
|
// Runs the initial validation
|
|
1365
1391
|
onMounted(() => {
|
|
1366
1392
|
if (validateOnMount) {
|
|
@@ -1377,7 +1403,13 @@ function _useField(name, rules, opts) {
|
|
|
1377
1403
|
}
|
|
1378
1404
|
let unwatchValue;
|
|
1379
1405
|
function watchValue() {
|
|
1380
|
-
unwatchValue = watch(value,
|
|
1406
|
+
unwatchValue = watch(value, (val, oldVal) => {
|
|
1407
|
+
if (es6(val, oldVal)) {
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
const validateFn = validateOnValueUpdate ? validateWithStateMutation : validateValidStateOnly;
|
|
1411
|
+
validateFn();
|
|
1412
|
+
}, {
|
|
1381
1413
|
deep: true,
|
|
1382
1414
|
});
|
|
1383
1415
|
}
|
|
@@ -1418,6 +1450,7 @@ function _useField(name, rules, opts) {
|
|
|
1418
1450
|
checkedValue,
|
|
1419
1451
|
uncheckedValue,
|
|
1420
1452
|
bails,
|
|
1453
|
+
keepValueOnUnmount,
|
|
1421
1454
|
resetField,
|
|
1422
1455
|
handleReset: () => resetField(),
|
|
1423
1456
|
validate: validate$1,
|
|
@@ -1455,13 +1488,14 @@ function _useField(name, rules, opts) {
|
|
|
1455
1488
|
// associate the field with the given form
|
|
1456
1489
|
form.register(field);
|
|
1457
1490
|
onBeforeUnmount(() => {
|
|
1491
|
+
markedForRemoval = true;
|
|
1458
1492
|
form.unregister(field);
|
|
1459
1493
|
});
|
|
1460
1494
|
// extract cross-field dependencies in a computed prop
|
|
1461
1495
|
const dependencies = computed(() => {
|
|
1462
1496
|
const rulesVal = normalizedRules.value;
|
|
1463
1497
|
// is falsy, a function schema or a yup schema
|
|
1464
|
-
if (!rulesVal || isCallable(rulesVal) || isYupValidator(rulesVal)) {
|
|
1498
|
+
if (!rulesVal || isCallable(rulesVal) || isYupValidator(rulesVal) || Array.isArray(rulesVal)) {
|
|
1465
1499
|
return {};
|
|
1466
1500
|
}
|
|
1467
1501
|
return Object.keys(rulesVal).reduce((acc, rule) => {
|
|
@@ -1503,6 +1537,9 @@ function normalizeOptions(name, opts) {
|
|
|
1503
1537
|
label: name,
|
|
1504
1538
|
validateOnValueUpdate: true,
|
|
1505
1539
|
standalone: false,
|
|
1540
|
+
keepValueOnUnmount: undefined,
|
|
1541
|
+
modelPropName: 'modelValue',
|
|
1542
|
+
syncVModel: true,
|
|
1506
1543
|
});
|
|
1507
1544
|
if (!opts) {
|
|
1508
1545
|
return defaults();
|
|
@@ -1534,8 +1571,8 @@ function useCheckboxField(name, rules, opts) {
|
|
|
1534
1571
|
return Array.isArray(currentValue) ? currentValue.includes(checkedVal) : checkedVal === currentValue;
|
|
1535
1572
|
});
|
|
1536
1573
|
function handleCheckboxChange(e, shouldValidate = true) {
|
|
1537
|
-
var _a
|
|
1538
|
-
if (checked.value === ((
|
|
1574
|
+
var _a;
|
|
1575
|
+
if (checked.value === ((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.checked)) {
|
|
1539
1576
|
return;
|
|
1540
1577
|
}
|
|
1541
1578
|
let newValue = normalizeEventValue(e);
|
|
@@ -1546,8 +1583,10 @@ function useCheckboxField(name, rules, opts) {
|
|
|
1546
1583
|
handleChange(newValue, shouldValidate);
|
|
1547
1584
|
}
|
|
1548
1585
|
onBeforeUnmount(() => {
|
|
1549
|
-
|
|
1550
|
-
|
|
1586
|
+
var _a, _b;
|
|
1587
|
+
const shouldKeepValue = (_b = (_a = unref(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : unref(form === null || form === void 0 ? void 0 : form.keepValuesOnUnmount)) !== null && _b !== void 0 ? _b : false;
|
|
1588
|
+
// toggles the checkbox value if it was checked and the unset behavior is set
|
|
1589
|
+
if (checked.value && !shouldKeepValue) {
|
|
1551
1590
|
handleCheckboxChange(unref(checkedValue), false);
|
|
1552
1591
|
}
|
|
1553
1592
|
});
|
|
@@ -1556,6 +1595,41 @@ function useCheckboxField(name, rules, opts) {
|
|
|
1556
1595
|
uncheckedValue, handleChange: handleCheckboxChange });
|
|
1557
1596
|
}
|
|
1558
1597
|
return patchCheckboxApi(_useField(name, rules, opts));
|
|
1598
|
+
}
|
|
1599
|
+
function useVModel({ prop, value, handleChange }) {
|
|
1600
|
+
const vm = getCurrentInstance();
|
|
1601
|
+
/* istanbul ignore next */
|
|
1602
|
+
if (!vm) {
|
|
1603
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
1604
|
+
console.warn('Failed to setup model events because `useField` was not called in setup.');
|
|
1605
|
+
}
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
const propName = prop || 'modelValue';
|
|
1609
|
+
const emitName = `update:${propName}`;
|
|
1610
|
+
// Component doesn't have a model prop setup (must be defined on the props)
|
|
1611
|
+
if (!(propName in vm.props)) {
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
watch(value, newValue => {
|
|
1615
|
+
if (es6(newValue, getCurrentModelValue(vm, propName))) {
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
vm.emit(emitName, newValue);
|
|
1619
|
+
});
|
|
1620
|
+
watch(() => getCurrentModelValue(vm, propName), propValue => {
|
|
1621
|
+
if (propValue === IS_ABSENT && value.value === undefined) {
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
const newValue = propValue === IS_ABSENT ? undefined : propValue;
|
|
1625
|
+
if (es6(newValue, applyModelModifiers(value.value, vm.props.modelModifiers))) {
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
handleChange(newValue);
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
function getCurrentModelValue(vm, propName) {
|
|
1632
|
+
return vm.props[propName];
|
|
1559
1633
|
}
|
|
1560
1634
|
|
|
1561
1635
|
const FieldImpl = defineComponent({
|
|
@@ -1622,13 +1696,17 @@ const FieldImpl = defineComponent({
|
|
|
1622
1696
|
type: Boolean,
|
|
1623
1697
|
default: false,
|
|
1624
1698
|
},
|
|
1699
|
+
keepValue: {
|
|
1700
|
+
type: Boolean,
|
|
1701
|
+
default: undefined,
|
|
1702
|
+
},
|
|
1625
1703
|
},
|
|
1626
1704
|
setup(props, ctx) {
|
|
1627
1705
|
const rules = toRef(props, 'rules');
|
|
1628
1706
|
const name = toRef(props, 'name');
|
|
1629
1707
|
const label = toRef(props, 'label');
|
|
1630
1708
|
const uncheckedValue = toRef(props, 'uncheckedValue');
|
|
1631
|
-
const
|
|
1709
|
+
const keepValue = toRef(props, 'keepValue');
|
|
1632
1710
|
const { errors, value, errorMessage, validate: validateField, handleChange, handleBlur, setTouched, resetField, handleReset, meta, checked, setErrors, } = useField(name, rules, {
|
|
1633
1711
|
validateOnMount: props.validateOnMount,
|
|
1634
1712
|
bails: props.bails,
|
|
@@ -1640,25 +1718,22 @@ const FieldImpl = defineComponent({
|
|
|
1640
1718
|
uncheckedValue,
|
|
1641
1719
|
label,
|
|
1642
1720
|
validateOnValueUpdate: false,
|
|
1721
|
+
keepValueOnUnmount: keepValue,
|
|
1643
1722
|
});
|
|
1644
1723
|
// If there is a v-model applied on the component we need to emit the `update:modelValue` whenever the value binding changes
|
|
1645
|
-
const onChangeHandler =
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
}
|
|
1650
|
-
: handleChange;
|
|
1724
|
+
const onChangeHandler = function handleChangeWithModel(e, shouldValidate = true) {
|
|
1725
|
+
handleChange(e, shouldValidate);
|
|
1726
|
+
ctx.emit('update:modelValue', value.value);
|
|
1727
|
+
};
|
|
1651
1728
|
const handleInput = (e) => {
|
|
1652
1729
|
if (!hasCheckedAttr(ctx.attrs.type)) {
|
|
1653
1730
|
value.value = normalizeEventValue(e);
|
|
1654
1731
|
}
|
|
1655
1732
|
};
|
|
1656
|
-
const onInputHandler =
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
}
|
|
1661
|
-
: handleInput;
|
|
1733
|
+
const onInputHandler = function handleInputWithModel(e) {
|
|
1734
|
+
handleInput(e);
|
|
1735
|
+
ctx.emit('update:modelValue', value.value);
|
|
1736
|
+
};
|
|
1662
1737
|
const fieldProps = computed(() => {
|
|
1663
1738
|
const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = resolveValidationTriggers(props);
|
|
1664
1739
|
const baseOnBlur = [handleBlur, ctx.attrs.onBlur, validateOnBlur ? validateField : undefined].filter(Boolean);
|
|
@@ -1670,32 +1745,16 @@ const FieldImpl = defineComponent({
|
|
|
1670
1745
|
onInput: baseOnInput,
|
|
1671
1746
|
onChange: baseOnChange,
|
|
1672
1747
|
};
|
|
1673
|
-
|
|
1674
|
-
attrs['onUpdate:modelValue'] = [onChangeHandler];
|
|
1675
|
-
}
|
|
1748
|
+
attrs['onUpdate:modelValue'] = e => onChangeHandler(e, validateOnModelUpdate);
|
|
1676
1749
|
if (hasCheckedAttr(ctx.attrs.type) && checked) {
|
|
1677
1750
|
attrs.checked = checked.value;
|
|
1678
1751
|
}
|
|
1679
|
-
else {
|
|
1680
|
-
attrs.value = value.value;
|
|
1681
|
-
}
|
|
1682
1752
|
const tag = resolveTag(props, ctx);
|
|
1683
1753
|
if (shouldHaveValueBinding(tag, ctx.attrs)) {
|
|
1684
|
-
|
|
1754
|
+
attrs.value = value.value;
|
|
1685
1755
|
}
|
|
1686
1756
|
return attrs;
|
|
1687
1757
|
});
|
|
1688
|
-
const modelValue = toRef(props, 'modelValue');
|
|
1689
|
-
watch(modelValue, newModelValue => {
|
|
1690
|
-
// Don't attempt to sync absent values
|
|
1691
|
-
if (newModelValue === IS_ABSENT && value.value === undefined) {
|
|
1692
|
-
return;
|
|
1693
|
-
}
|
|
1694
|
-
if (newModelValue !== applyModifiers(value.value, props.modelModifiers)) {
|
|
1695
|
-
value.value = newModelValue === IS_ABSENT ? undefined : newModelValue;
|
|
1696
|
-
validateField();
|
|
1697
|
-
}
|
|
1698
|
-
});
|
|
1699
1758
|
function slotProps() {
|
|
1700
1759
|
return {
|
|
1701
1760
|
field: fieldProps.value,
|
|
@@ -1747,12 +1806,6 @@ function resolveValidationTriggers(props) {
|
|
|
1747
1806
|
validateOnModelUpdate: (_d = props.validateOnModelUpdate) !== null && _d !== void 0 ? _d : validateOnModelUpdate,
|
|
1748
1807
|
};
|
|
1749
1808
|
}
|
|
1750
|
-
function applyModifiers(value, modifiers) {
|
|
1751
|
-
if (modifiers.number) {
|
|
1752
|
-
return toNumber(value);
|
|
1753
|
-
}
|
|
1754
|
-
return value;
|
|
1755
|
-
}
|
|
1756
1809
|
function resolveInitialValue(props, ctx) {
|
|
1757
1810
|
// Gets the initial value either from `value` prop/attr or `v-model` binding (modelValue)
|
|
1758
1811
|
// For checkboxes and radio buttons it will always be the model value not the `value` attribute
|
|
@@ -1765,15 +1818,19 @@ const Field = FieldImpl;
|
|
|
1765
1818
|
|
|
1766
1819
|
let FORM_COUNTER = 0;
|
|
1767
1820
|
function useForm(opts) {
|
|
1821
|
+
var _a;
|
|
1768
1822
|
const formId = FORM_COUNTER++;
|
|
1823
|
+
// Prevents fields from double resetting their values, which causes checkboxes to toggle their initial value
|
|
1824
|
+
// TODO: This won't be needed if we centralize all the state inside the `form` for form inputs
|
|
1825
|
+
let RESET_LOCK = false;
|
|
1769
1826
|
// A lookup containing fields or field groups
|
|
1770
1827
|
const fieldsByPath = ref({});
|
|
1771
1828
|
// If the form is currently submitting
|
|
1772
1829
|
const isSubmitting = ref(false);
|
|
1773
1830
|
// The number of times the user tried to submit the form
|
|
1774
1831
|
const submitCount = ref(0);
|
|
1775
|
-
//
|
|
1776
|
-
const
|
|
1832
|
+
// field arrays managed by this form
|
|
1833
|
+
const fieldArrays = [];
|
|
1777
1834
|
// a private ref for all form values
|
|
1778
1835
|
const formValues = reactive(klona(unref(opts === null || opts === void 0 ? void 0 : opts.initialValues) || {}));
|
|
1779
1836
|
// the source of errors for the form fields
|
|
@@ -1820,10 +1877,11 @@ function useForm(opts) {
|
|
|
1820
1877
|
// mutable non-reactive reference to initial errors
|
|
1821
1878
|
// we need this to process initial errors then unset them
|
|
1822
1879
|
const initialErrors = Object.assign({}, ((opts === null || opts === void 0 ? void 0 : opts.initialErrors) || {}));
|
|
1880
|
+
const keepValuesOnUnmount = (_a = opts === null || opts === void 0 ? void 0 : opts.keepValuesOnUnmount) !== null && _a !== void 0 ? _a : false;
|
|
1823
1881
|
// initial form values
|
|
1824
1882
|
const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(fieldsByPath, formValues, opts === null || opts === void 0 ? void 0 : opts.initialValues);
|
|
1825
1883
|
// form meta aggregations
|
|
1826
|
-
const meta = useFormMeta(fieldsByPath, formValues,
|
|
1884
|
+
const meta = useFormMeta(fieldsByPath, formValues, originalInitialValues, errors);
|
|
1827
1885
|
const schema = opts === null || opts === void 0 ? void 0 : opts.validationSchema;
|
|
1828
1886
|
const formCtx = {
|
|
1829
1887
|
formId,
|
|
@@ -1835,7 +1893,8 @@ function useForm(opts) {
|
|
|
1835
1893
|
submitCount,
|
|
1836
1894
|
meta,
|
|
1837
1895
|
isSubmitting,
|
|
1838
|
-
|
|
1896
|
+
fieldArrays,
|
|
1897
|
+
keepValuesOnUnmount,
|
|
1839
1898
|
validateSchema: unref(schema) ? validateSchema : undefined,
|
|
1840
1899
|
validate,
|
|
1841
1900
|
register: registerField,
|
|
@@ -1853,6 +1912,7 @@ function useForm(opts) {
|
|
|
1853
1912
|
stageInitialValue,
|
|
1854
1913
|
unsetInitialValue,
|
|
1855
1914
|
setFieldInitialValue,
|
|
1915
|
+
useFieldModel,
|
|
1856
1916
|
};
|
|
1857
1917
|
function isFieldGroup(fieldOrGroup) {
|
|
1858
1918
|
return Array.isArray(fieldOrGroup);
|
|
@@ -1863,6 +1923,15 @@ function useForm(opts) {
|
|
|
1863
1923
|
}
|
|
1864
1924
|
return mutation(fieldOrGroup);
|
|
1865
1925
|
}
|
|
1926
|
+
function mutateAllFields(mutation) {
|
|
1927
|
+
Object.values(fieldsByPath.value).forEach(field => {
|
|
1928
|
+
if (!field) {
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
// avoid resetting the field values, because they should've been reset already.
|
|
1932
|
+
applyFieldMutation(field, mutation);
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1866
1935
|
/**
|
|
1867
1936
|
* Manually sets an error message on a specific field
|
|
1868
1937
|
*/
|
|
@@ -1887,15 +1956,15 @@ function useForm(opts) {
|
|
|
1887
1956
|
setInPath(formValues, field, clonedValue);
|
|
1888
1957
|
return;
|
|
1889
1958
|
}
|
|
1890
|
-
// Multiple checkboxes, and only one of them got updated
|
|
1891
1959
|
if (isFieldGroup(fieldInstance) && ((_a = fieldInstance[0]) === null || _a === void 0 ? void 0 : _a.type) === 'checkbox' && !Array.isArray(value)) {
|
|
1960
|
+
// Multiple checkboxes, and only one of them got updated
|
|
1892
1961
|
const newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field) || [], value, undefined));
|
|
1893
1962
|
setInPath(formValues, field, newValue);
|
|
1894
1963
|
return;
|
|
1895
1964
|
}
|
|
1896
1965
|
let newValue = value;
|
|
1897
1966
|
// Single Checkbox: toggles the field value unless the field is being reset then force it
|
|
1898
|
-
if (!isFieldGroup(fieldInstance) && fieldInstance.type === 'checkbox' && !force) {
|
|
1967
|
+
if (!isFieldGroup(fieldInstance) && fieldInstance.type === 'checkbox' && !force && !RESET_LOCK) {
|
|
1899
1968
|
newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field), value, unref(fieldInstance.uncheckedValue)));
|
|
1900
1969
|
}
|
|
1901
1970
|
setInPath(formValues, field, newValue);
|
|
@@ -1913,7 +1982,22 @@ function useForm(opts) {
|
|
|
1913
1982
|
setFieldValue(path, fields[path]);
|
|
1914
1983
|
});
|
|
1915
1984
|
// regenerate the arrays when the form values change
|
|
1916
|
-
|
|
1985
|
+
fieldArrays.forEach(f => f && f.reset());
|
|
1986
|
+
}
|
|
1987
|
+
function createModel(path) {
|
|
1988
|
+
const { value } = _useFieldValue(path);
|
|
1989
|
+
watch(value, () => {
|
|
1990
|
+
if (!fieldExists(unref(path))) {
|
|
1991
|
+
validate({ mode: 'validated-only' });
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
return value;
|
|
1995
|
+
}
|
|
1996
|
+
function useFieldModel(path) {
|
|
1997
|
+
if (!Array.isArray(path)) {
|
|
1998
|
+
return createModel(path);
|
|
1999
|
+
}
|
|
2000
|
+
return path.map(createModel);
|
|
1917
2001
|
}
|
|
1918
2002
|
/**
|
|
1919
2003
|
* Sets the touched meta state on a field
|
|
@@ -1936,6 +2020,7 @@ function useForm(opts) {
|
|
|
1936
2020
|
* Resets all fields
|
|
1937
2021
|
*/
|
|
1938
2022
|
function resetForm(state) {
|
|
2023
|
+
RESET_LOCK = true;
|
|
1939
2024
|
// set initial values if provided
|
|
1940
2025
|
if (state === null || state === void 0 ? void 0 : state.values) {
|
|
1941
2026
|
setInitialValues(state.values);
|
|
@@ -1947,17 +2032,16 @@ function useForm(opts) {
|
|
|
1947
2032
|
// otherwise clean the current values
|
|
1948
2033
|
setValues(originalInitialValues.value);
|
|
1949
2034
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
return;
|
|
1953
|
-
}
|
|
1954
|
-
applyFieldMutation(field, f => f.resetField());
|
|
1955
|
-
});
|
|
2035
|
+
// avoid resetting the field values, because they should've been reset already.
|
|
2036
|
+
mutateAllFields(f => f.resetField());
|
|
1956
2037
|
if (state === null || state === void 0 ? void 0 : state.touched) {
|
|
1957
2038
|
setTouched(state.touched);
|
|
1958
2039
|
}
|
|
1959
2040
|
setErrors((state === null || state === void 0 ? void 0 : state.errors) || {});
|
|
1960
2041
|
submitCount.value = (state === null || state === void 0 ? void 0 : state.submitCount) || 0;
|
|
2042
|
+
nextTick(() => {
|
|
2043
|
+
RESET_LOCK = false;
|
|
2044
|
+
});
|
|
1961
2045
|
}
|
|
1962
2046
|
function insertFieldAtPath(field, path) {
|
|
1963
2047
|
const rawField = markRaw(field);
|
|
@@ -2013,6 +2097,8 @@ function useForm(opts) {
|
|
|
2013
2097
|
insertFieldAtPath(field, newPath);
|
|
2014
2098
|
// re-validate if either path had errors before
|
|
2015
2099
|
if (errors.value[oldPath] || errors.value[newPath]) {
|
|
2100
|
+
// clear up both paths errors
|
|
2101
|
+
setFieldError(oldPath, undefined);
|
|
2016
2102
|
validateField(newPath);
|
|
2017
2103
|
}
|
|
2018
2104
|
// clean up the old path if no other field is sharing that name
|
|
@@ -2035,18 +2121,32 @@ function useForm(opts) {
|
|
|
2035
2121
|
}
|
|
2036
2122
|
function unregisterField(field) {
|
|
2037
2123
|
const fieldName = unref(field.name);
|
|
2124
|
+
const fieldInstance = fieldsByPath.value[fieldName];
|
|
2125
|
+
const isGroup = !!fieldInstance && isFieldGroup(fieldInstance);
|
|
2038
2126
|
removeFieldFromPath(field, fieldName);
|
|
2039
2127
|
nextTick(() => {
|
|
2128
|
+
var _a;
|
|
2040
2129
|
// clears a field error on unmounted
|
|
2041
2130
|
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
|
|
2042
2131
|
// #3384
|
|
2043
2132
|
if (!fieldExists(fieldName)) {
|
|
2044
2133
|
setFieldError(fieldName, undefined);
|
|
2134
|
+
// Checks if the field was configured to be unset during unmount or not
|
|
2135
|
+
// Checks both the form-level config and field-level one
|
|
2136
|
+
// Field has the priority if it is set, otherwise it goes to the form settings
|
|
2137
|
+
const shouldKeepValue = (_a = unref(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : unref(keepValuesOnUnmount);
|
|
2138
|
+
if (shouldKeepValue) {
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
if (isGroup && !isEmptyContainer(getFromPath(formValues, fieldName))) {
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2045
2144
|
unsetPath(formValues, fieldName);
|
|
2046
2145
|
}
|
|
2047
2146
|
});
|
|
2048
2147
|
}
|
|
2049
2148
|
async function validate(opts) {
|
|
2149
|
+
mutateAllFields(f => (f.meta.validated = true));
|
|
2050
2150
|
if (formCtx.validateSchema) {
|
|
2051
2151
|
return formCtx.validateSchema((opts === null || opts === void 0 ? void 0 : opts.mode) || 'force');
|
|
2052
2152
|
}
|
|
@@ -2147,9 +2247,12 @@ function useForm(opts) {
|
|
|
2147
2247
|
/**
|
|
2148
2248
|
* Sneaky function to set initial field values
|
|
2149
2249
|
*/
|
|
2150
|
-
function stageInitialValue(path, value) {
|
|
2250
|
+
function stageInitialValue(path, value, updateOriginal = false) {
|
|
2151
2251
|
setInPath(formValues, path, value);
|
|
2152
2252
|
setFieldInitialValue(path, value);
|
|
2253
|
+
if (updateOriginal) {
|
|
2254
|
+
setInPath(originalInitialValues.value, path, klona(value));
|
|
2255
|
+
}
|
|
2153
2256
|
}
|
|
2154
2257
|
async function _validateSchema() {
|
|
2155
2258
|
const schemaValue = unref(schema);
|
|
@@ -2166,10 +2269,12 @@ function useForm(opts) {
|
|
|
2166
2269
|
}
|
|
2167
2270
|
/**
|
|
2168
2271
|
* Batches validation runs in 5ms batches
|
|
2272
|
+
* Must have two distinct batch queues to make sure they don't override each other settings #3783
|
|
2169
2273
|
*/
|
|
2170
|
-
const
|
|
2274
|
+
const debouncedSilentValidation = debounceAsync(_validateSchema, 5);
|
|
2275
|
+
const debouncedValidation = debounceAsync(_validateSchema, 5);
|
|
2171
2276
|
async function validateSchema(mode) {
|
|
2172
|
-
const formResult = await
|
|
2277
|
+
const formResult = await (mode === 'silent' ? debouncedSilentValidation() : debouncedValidation());
|
|
2173
2278
|
// fields by id lookup
|
|
2174
2279
|
const fieldsById = formCtx.fieldsByPath.value || {};
|
|
2175
2280
|
// errors fields names, we need it to also check if custom errors are updated
|
|
@@ -2265,6 +2370,7 @@ function useForm(opts) {
|
|
|
2265
2370
|
setValues,
|
|
2266
2371
|
setFieldTouched,
|
|
2267
2372
|
setTouched,
|
|
2373
|
+
useFieldModel,
|
|
2268
2374
|
};
|
|
2269
2375
|
}
|
|
2270
2376
|
/**
|
|
@@ -2279,16 +2385,23 @@ function useFormMeta(fieldsByPath, currentValues, initialValues, errors) {
|
|
|
2279
2385
|
const isDirty = computed(() => {
|
|
2280
2386
|
return !es6(currentValues, unref(initialValues));
|
|
2281
2387
|
});
|
|
2282
|
-
|
|
2388
|
+
function calculateFlags() {
|
|
2283
2389
|
const fields = Object.values(fieldsByPath.value).flat(1).filter(Boolean);
|
|
2284
2390
|
return keysOf(MERGE_STRATEGIES).reduce((acc, flag) => {
|
|
2285
2391
|
const mergeMethod = MERGE_STRATEGIES[flag];
|
|
2286
2392
|
acc[flag] = fields[mergeMethod](field => field.meta[flag]);
|
|
2287
2393
|
return acc;
|
|
2288
2394
|
}, {});
|
|
2395
|
+
}
|
|
2396
|
+
const flags = reactive(calculateFlags());
|
|
2397
|
+
watchEffect(() => {
|
|
2398
|
+
const value = calculateFlags();
|
|
2399
|
+
flags.touched = value.touched;
|
|
2400
|
+
flags.valid = value.valid;
|
|
2401
|
+
flags.pending = value.pending;
|
|
2289
2402
|
});
|
|
2290
2403
|
return computed(() => {
|
|
2291
|
-
return Object.assign(Object.assign({ initialValues: unref(initialValues) }, flags
|
|
2404
|
+
return Object.assign(Object.assign({ initialValues: unref(initialValues) }, flags), { valid: flags.valid && !keysOf(errors.value).length, dirty: isDirty.value });
|
|
2292
2405
|
});
|
|
2293
2406
|
}
|
|
2294
2407
|
/**
|
|
@@ -2409,16 +2522,22 @@ const FormImpl = defineComponent({
|
|
|
2409
2522
|
type: Function,
|
|
2410
2523
|
default: undefined,
|
|
2411
2524
|
},
|
|
2525
|
+
keepValues: {
|
|
2526
|
+
type: Boolean,
|
|
2527
|
+
default: false,
|
|
2528
|
+
},
|
|
2412
2529
|
},
|
|
2413
2530
|
setup(props, ctx) {
|
|
2414
2531
|
const initialValues = toRef(props, 'initialValues');
|
|
2415
2532
|
const validationSchema = toRef(props, 'validationSchema');
|
|
2533
|
+
const keepValues = toRef(props, 'keepValues');
|
|
2416
2534
|
const { errors, values, meta, isSubmitting, submitCount, validate, validateField, handleReset, resetForm, handleSubmit, submitForm, setErrors, setFieldError, setFieldValue, setValues, setFieldTouched, setTouched, } = useForm({
|
|
2417
2535
|
validationSchema: validationSchema.value ? validationSchema : undefined,
|
|
2418
2536
|
initialValues,
|
|
2419
2537
|
initialErrors: props.initialErrors,
|
|
2420
2538
|
initialTouched: props.initialTouched,
|
|
2421
2539
|
validateOnMount: props.validateOnMount,
|
|
2540
|
+
keepValuesOnUnmount: keepValues,
|
|
2422
2541
|
});
|
|
2423
2542
|
const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit, props.onInvalidSubmit) : submitForm;
|
|
2424
2543
|
function handleFormReset(e) {
|
|
@@ -2488,15 +2607,13 @@ const FormImpl = defineComponent({
|
|
|
2488
2607
|
});
|
|
2489
2608
|
const Form = FormImpl;
|
|
2490
2609
|
|
|
2491
|
-
let FIELD_ARRAY_COUNTER = 0;
|
|
2492
2610
|
function useFieldArray(arrayPath) {
|
|
2493
|
-
const id = FIELD_ARRAY_COUNTER++;
|
|
2494
2611
|
const form = injectWithSelf(FormContextKey, undefined);
|
|
2495
2612
|
const fields = ref([]);
|
|
2496
2613
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2497
2614
|
const noOp = () => { };
|
|
2498
2615
|
const noOpApi = {
|
|
2499
|
-
fields
|
|
2616
|
+
fields,
|
|
2500
2617
|
remove: noOp,
|
|
2501
2618
|
push: noOp,
|
|
2502
2619
|
swap: noOp,
|
|
@@ -2504,6 +2621,7 @@ function useFieldArray(arrayPath) {
|
|
|
2504
2621
|
update: noOp,
|
|
2505
2622
|
replace: noOp,
|
|
2506
2623
|
prepend: noOp,
|
|
2624
|
+
move: noOp,
|
|
2507
2625
|
};
|
|
2508
2626
|
if (!form) {
|
|
2509
2627
|
warn('FieldArray requires being a child of `<Form/>` or `useForm` being called before it. Array fields may not work correctly');
|
|
@@ -2513,9 +2631,13 @@ function useFieldArray(arrayPath) {
|
|
|
2513
2631
|
warn('FieldArray requires a field path to be provided, did you forget to pass the `name` prop?');
|
|
2514
2632
|
return noOpApi;
|
|
2515
2633
|
}
|
|
2634
|
+
const alreadyExists = form.fieldArrays.find(a => unref(a.path) === unref(arrayPath));
|
|
2635
|
+
if (alreadyExists) {
|
|
2636
|
+
return alreadyExists;
|
|
2637
|
+
}
|
|
2516
2638
|
let entryCounter = 0;
|
|
2517
2639
|
function initFields() {
|
|
2518
|
-
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []);
|
|
2640
|
+
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []) || [];
|
|
2519
2641
|
fields.value = currentValues.map(createEntry);
|
|
2520
2642
|
updateEntryFlags();
|
|
2521
2643
|
}
|
|
@@ -2532,10 +2654,20 @@ function useFieldArray(arrayPath) {
|
|
|
2532
2654
|
const key = entryCounter++;
|
|
2533
2655
|
const entry = {
|
|
2534
2656
|
key,
|
|
2535
|
-
value: computed(
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2657
|
+
value: computed({
|
|
2658
|
+
get() {
|
|
2659
|
+
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []) || [];
|
|
2660
|
+
const idx = fields.value.findIndex(e => e.key === key);
|
|
2661
|
+
return idx === -1 ? value : currentValues[idx];
|
|
2662
|
+
},
|
|
2663
|
+
set(value) {
|
|
2664
|
+
const idx = fields.value.findIndex(e => e.key === key);
|
|
2665
|
+
if (idx === -1) {
|
|
2666
|
+
warn(`Attempting to update a non-existent array item`);
|
|
2667
|
+
return;
|
|
2668
|
+
}
|
|
2669
|
+
update(idx, value);
|
|
2670
|
+
},
|
|
2539
2671
|
}),
|
|
2540
2672
|
isFirst: false,
|
|
2541
2673
|
isLast: false,
|
|
@@ -2572,7 +2704,7 @@ function useFieldArray(arrayPath) {
|
|
|
2572
2704
|
function swap(indexA, indexB) {
|
|
2573
2705
|
const pathName = unref(arrayPath);
|
|
2574
2706
|
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2575
|
-
if (!Array.isArray(pathValue) || !
|
|
2707
|
+
if (!Array.isArray(pathValue) || !(indexA in pathValue) || !(indexB in pathValue)) {
|
|
2576
2708
|
return;
|
|
2577
2709
|
}
|
|
2578
2710
|
const newValue = [...pathValue];
|
|
@@ -2628,14 +2760,26 @@ function useFieldArray(arrayPath) {
|
|
|
2628
2760
|
fields.value.unshift(createEntry(value));
|
|
2629
2761
|
updateEntryFlags();
|
|
2630
2762
|
}
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2763
|
+
function move(oldIdx, newIdx) {
|
|
2764
|
+
const pathName = unref(arrayPath);
|
|
2765
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2766
|
+
const newValue = isNullOrUndefined(pathValue) ? [] : [...pathValue];
|
|
2767
|
+
if (!Array.isArray(pathValue) || !(oldIdx in pathValue) || !(newIdx in pathValue)) {
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2770
|
+
const newFields = [...fields.value];
|
|
2771
|
+
const movedItem = newFields[oldIdx];
|
|
2772
|
+
newFields.splice(oldIdx, 1);
|
|
2773
|
+
newFields.splice(newIdx, 0, movedItem);
|
|
2774
|
+
const movedValue = newValue[oldIdx];
|
|
2775
|
+
newValue.splice(oldIdx, 1);
|
|
2776
|
+
newValue.splice(newIdx, 0, movedValue);
|
|
2777
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2778
|
+
fields.value = newFields;
|
|
2779
|
+
updateEntryFlags();
|
|
2780
|
+
}
|
|
2781
|
+
const fieldArrayCtx = {
|
|
2782
|
+
fields,
|
|
2639
2783
|
remove,
|
|
2640
2784
|
push,
|
|
2641
2785
|
swap,
|
|
@@ -2643,7 +2787,16 @@ function useFieldArray(arrayPath) {
|
|
|
2643
2787
|
update,
|
|
2644
2788
|
replace,
|
|
2645
2789
|
prepend,
|
|
2790
|
+
move,
|
|
2646
2791
|
};
|
|
2792
|
+
form.fieldArrays.push(Object.assign({ path: arrayPath, reset: initFields }, fieldArrayCtx));
|
|
2793
|
+
onBeforeUnmount(() => {
|
|
2794
|
+
const idx = form.fieldArrays.findIndex(i => unref(i.path) === unref(arrayPath));
|
|
2795
|
+
if (idx >= 0) {
|
|
2796
|
+
form.fieldArrays.splice(idx, 1);
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
return fieldArrayCtx;
|
|
2647
2800
|
}
|
|
2648
2801
|
|
|
2649
2802
|
const FieldArrayImpl = defineComponent({
|
|
@@ -2656,7 +2809,7 @@ const FieldArrayImpl = defineComponent({
|
|
|
2656
2809
|
},
|
|
2657
2810
|
},
|
|
2658
2811
|
setup(props, ctx) {
|
|
2659
|
-
const { push, remove, swap, insert, replace, update, prepend, fields } = useFieldArray(toRef(props, 'name'));
|
|
2812
|
+
const { push, remove, swap, insert, replace, update, prepend, move, fields } = useFieldArray(toRef(props, 'name'));
|
|
2660
2813
|
function slotProps() {
|
|
2661
2814
|
return {
|
|
2662
2815
|
fields: fields.value,
|
|
@@ -2667,6 +2820,7 @@ const FieldArrayImpl = defineComponent({
|
|
|
2667
2820
|
update,
|
|
2668
2821
|
replace,
|
|
2669
2822
|
prepend,
|
|
2823
|
+
move,
|
|
2670
2824
|
};
|
|
2671
2825
|
}
|
|
2672
2826
|
ctx.expose({
|
|
@@ -2677,6 +2831,7 @@ const FieldArrayImpl = defineComponent({
|
|
|
2677
2831
|
update,
|
|
2678
2832
|
replace,
|
|
2679
2833
|
prepend,
|
|
2834
|
+
move,
|
|
2680
2835
|
});
|
|
2681
2836
|
return () => {
|
|
2682
2837
|
const children = normalizeChildren(undefined, ctx, slotProps);
|
|
@@ -2976,4 +3131,4 @@ function useSubmitForm(cb) {
|
|
|
2976
3131
|
};
|
|
2977
3132
|
}
|
|
2978
3133
|
|
|
2979
|
-
export { ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, configure, defineRule, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate };
|
|
3134
|
+
export { ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, IS_ABSENT, configure, defineRule, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate };
|