Skip to content

Commit 19d0a6b

Browse files
Add docs about useFieldArray composable
Signed-off-by: Kiran Parajuli <[email protected]>
1 parent a376ce5 commit 19d0a6b

File tree

13 files changed

+221
-99
lines changed

13 files changed

+221
-99
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"highlight.js": "^11.11.1",
1919
"pinia": "^2.3.0",
2020
"vue": "^3.5.13",
21-
"vue-formik": "^0.1.30",
21+
"vue-formik": "^0.1.34",
2222
"vue-router": "^4.5.0",
2323
"yup": "^1.6.1"
2424
},

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/TheAppbar.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ defineProps<{
1313
<h1><router-link to="/" class="!no-underline">Vue Formik</router-link></h1>
1414
<div class="grow hidden sm:block" />
1515
<router-link class="hidden sm:block" to="/about">About</router-link>
16+
<router-link class="hidden sm:block" to="/demo">Demo</router-link>
1617
<a class="hidden sm:block" href="https://github.com/vue-formik/vue-formik" target="_blank">
1718
⭐ Star us on GitHub
1819
</a>

src/components/home/ExpoForm.vue

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<form class="border border-gray-500 rounded-md p-4" @submit="(e) => {}">
2+
<FormikForm class="border border-gray-500 rounded-md p-4">
33
<FormInput name="name" label="Name:" type="text" placeholder="Enter your name" />
44

55
<FormInput
@@ -29,14 +29,7 @@
2929
class="secondary-outlined-btn size-11"
3030
title="Remove contact"
3131
:disabled="formik.values.contacts.length <= 1"
32-
@click="
33-
() => {
34-
formik.setValues({
35-
...formik.values,
36-
contacts: formik.values.contacts.filter((_, i) => i !== index),
37-
});
38-
}
39-
"
32+
@click="() => fieldArray.pop('contacts', index)"
4033
>
4134
x
4235
</button>
@@ -45,14 +38,7 @@
4538
<button
4639
type="button"
4740
class="secondary-outlined-btn mt-8 w-fit"
48-
@click="
49-
() => {
50-
formik.setValues({
51-
...formik.values,
52-
contacts: [...formik.values.contacts, { code: '', number: '' }],
53-
});
54-
}
55-
"
41+
@click="() => fieldArray.push('contacts', { code: '', number: '' })"
5642
>
5743
Add contact
5844
</button>
@@ -86,14 +72,7 @@
8672
class="secondary-outlined-btn size-11"
8773
title="Remove address"
8874
:disabled="formik.values.addresses.length <= 1"
89-
@click="
90-
() => {
91-
formik.setValues({
92-
...formik.values,
93-
addresses: formik.values.addresses.filter((_, i) => i !== index),
94-
});
95-
}
96-
"
75+
@click="() => fieldArray.pop('addresses', index)"
9776
>
9877
x
9978
</button>
@@ -103,14 +82,7 @@
10382
<button
10483
type="button"
10584
class="secondary-outlined-btn"
106-
@click="
107-
() => {
108-
formik.setValues({
109-
...formik.values,
110-
addresses: [...formik.values.addresses, ''],
111-
});
112-
}
113-
"
85+
@click="() => fieldArray.push('addresses', '')"
11486
>
11587
Add address
11688
</button>
@@ -121,7 +93,7 @@
12193
<button type="submit" class="primary-btn w-fit" :disabled="!formik.isValid.value">
12294
Submit
12395
</button>
124-
</form>
96+
</FormikForm>
12597
<div class="overflow-auto border border-gray-500 p-4 rounded-md h-full text-sm">
12698
<pre><code>{{JSON.stringify({
12799
values: formik.values,
@@ -135,12 +107,21 @@
135107

136108
<script setup lang="ts">
137109
/* eslint-disable @typescript-eslint/no-explicit-any */
138-
import { FormInput, FormSelectField, FormTextArea } from "vue-formik";
139-
import useFormikForm from "@/composables/formik.ts";
140-
import { provide } from "vue";
110+
import {
111+
FormInput,
112+
FormSelectField,
113+
FormTextArea,
114+
useFormik,
115+
FormikForm,
116+
useFieldArray,
117+
} from "vue-formik";
118+
import { computed, provide } from "vue";
119+
import { DemoTabValues, InitialValues } from "@/constants/demo.ts";
141120
142121
const props = defineProps<{
143122
validationSchema: any;
123+
value: number;
124+
validateOnMount: boolean;
144125
}>();
145126
146127
const sexOptions = [
@@ -150,7 +131,23 @@ const sexOptions = [
150131
{ label: "Prefer not to say", value: "N/A" },
151132
];
152133
153-
const { formik } = useFormikForm(props.validationSchema);
134+
const opts = computed(() => ({
135+
validationSchema: props.value === DemoTabValues.CUSTOM ? props.validationSchema : undefined,
136+
yupSchema: props.value === DemoTabValues.YUP ? props.validationSchema : undefined,
137+
validateOnMount: props.validateOnMount,
138+
}));
154139
155-
provide("formik", formik);
140+
const formik = computed(() =>
141+
useFormik({
142+
initialValues: InitialValues,
143+
...opts.value,
144+
onSubmit: (values: any) => {
145+
console.log("Submitted:", values);
146+
},
147+
}),
148+
);
149+
150+
const fieldArray = computed(() => useFieldArray(formik.value));
151+
152+
provide("formik", formik.value);
156153
</script>

src/composables/formik.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/constants/homeFormik.ts renamed to src/constants/demo.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import * as Yup from "yup";
22

3+
export const DemoTabValues = {
4+
CUSTOM: 1,
5+
YUP: 0,
6+
};
7+
38
interface IContact {
49
code: string;
510
number: string;
611
}
712

8-
const InitialValues = {
13+
export const InitialValues = {
914
name: "",
1015
email: "",
1116
contacts: [{ code: "", number: "" }],
@@ -14,7 +19,7 @@ const InitialValues = {
1419
addresses: [""],
1520
};
1621

17-
const ValidationSchema = {
22+
export const ValidationSchema = {
1823
name: (value: string) => {
1924
if (!value) {
2025
return "Name is required";
@@ -80,13 +85,12 @@ const ValidationSchema = {
8085
errs[i] = "Address must be at most 50 characters";
8186
}
8287
}
83-
console.log(errs);
8488

8589
return errs.length ? errs : undefined;
8690
},
8791
};
8892

89-
const ValidationSchemaYup = Yup.object().shape({
93+
export const ValidationSchemaYup = Yup.object().shape({
9094
name: Yup.string().required("Name is required"),
9195
email: Yup.string().email("Invalid email").required("Email is required"),
9296
contacts: Yup.array()
@@ -117,4 +121,7 @@ const ValidationSchemaYup = Yup.object().shape({
117121
.default([""]), // Ensures addresses array is initialized
118122
});
119123

120-
export { InitialValues, ValidationSchemaYup, ValidationSchema };
124+
export const DemoTabs = [
125+
{ name: "Custom", value: DemoTabValues.CUSTOM, schema: ValidationSchema },
126+
{ name: "Yup", value: DemoTabValues.YUP, schema: ValidationSchemaYup },
127+
];

src/constants/theSidebarItems.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ export default [
88
},
99
{
1010
name: "Composable",
11-
children: [{ name: "useFormik", path: "/docs/composable/use-formik" }],
11+
children: [
12+
{ name: "useFormik", path: "/docs/composable/use-formik" },
13+
{ name: "useFieldArray", path: "/docs/composable/use-field-array" },
14+
],
1215
},
1316
{
1417
name: "Components",

src/router/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ const router = createRouter({
4343
path: "use-formik",
4444
component: () => import("@/views/libDocs/composables/useFormik/UseFormikView.vue"),
4545
},
46+
{
47+
path: "use-field-array",
48+
component: () => import("@/views/libDocs/composables/UseFieldArrayView.vue"),
49+
},
4650
],
4751
},
4852
{

src/views/DemoView.vue

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,30 @@
55

66
<div class="mb-4 border-b">
77
<button
8-
:class="{ 'bg-gray-800 text-white': tab === 1 }"
9-
class="py-2 px-4 mr-2"
10-
@click="() => (tab = 1)"
8+
v-for="tabItem in DemoTabs"
9+
:key="tabItem.value"
10+
:class="{ 'bg-gray-800 text-white': tab === tabItem.value }"
11+
class="py-2 px-4 mr-2 last:mr-0"
12+
@click="() => (tab = tabItem.value)"
1113
>
12-
Custom
13-
</button>
14-
<button
15-
:class="{ 'bg-gray-800 text-white': tab === 0 }"
16-
class="py-2 px-4 mr-2"
17-
@click="() => (tab = 0)"
18-
>
19-
Yup
14+
{{ tabItem.name }}
2015
</button>
16+
17+
<label for="validateOnMount">
18+
<input id="validateOnMount" v-model="validateOnMount" type="checkbox" class="ml-4" />
19+
<span class="ml-2">Validate on mount</span>
20+
</label>
2121
</div>
2222

2323
<div class="pg-view__content">
24-
<ExpoForm v-if="tab === 1" :validation-schema="ValidationSchema" />
25-
<ExpoForm v-else :validation-schema="ValidationSchemaYup" />
24+
<template v-for="tabItem in DemoTabs" :key="tabItem.value">
25+
<ExpoForm
26+
v-if="tab === tabItem.value"
27+
:validation-schema="tabItem.schema"
28+
:value="tab"
29+
:validate-on-mount="validateOnMount"
30+
/>
31+
</template>
2632

2733
<ValidationSchemaPreview />
2834
</div>
@@ -46,11 +52,12 @@
4652
import { onBeforeMount, ref } from "vue";
4753
import ValidationSchemaPreview from "@/components/home/ValidationSchemaPreview.vue";
4854
import ExpoForm from "@/components/home/ExpoForm.vue";
49-
import { ValidationSchema, ValidationSchemaYup } from "@/constants/homeFormik.ts";
55+
import { DemoTabs } from "@/constants/demo.ts";
5056
5157
onBeforeMount(() => {
5258
document.title = "Home | Vue Formik";
5359
});
5460
55-
const tab = ref<number>(1);
61+
const tab = ref(1);
62+
const validateOnMount = ref(false);
5663
</script>

src/views/gettingStarted/IntroductionView.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,17 @@
4848
</li>
4949
<li>
5050
You can create custom validation functions or integrate a library like
51-
<a href="https://github.com/jquense/yup" target="_blank" title="Yup">Yup</a> for
52-
schema-based validation.
51+
<a href="https://github.com/jquense/yup" target="_blank" title="Yup" class="text-primary"
52+
>Yup</a
53+
>, <a href="https://joi.dev/" target="_blank" title="Joi" class="text-primary">Joi</a>, or
54+
<a href="https://zod.dev/" target="_blank" title="Zod" class="text-primary">Zod</a>
55+
56+
for schema-based validation.
5357
</li>
5458

5559
<li>
5660
Future plans include extending support to other popular validation libraries, such as
57-
<a href="https://zod.dev/" target="_blank" title="Zod">Zod</a> and
58-
<a href="https://joi.dev/" target="_blank" title="Joi">Joi</a>, ensuring maximum
59-
flexibility and compatibility. 🌟
61+
VeeValidate and Vuelidate, ensuring maximum flexibility and compatibility. 🌟
6062
</li>
6163
</ol>
6264
</blockquote>

0 commit comments

Comments
 (0)