Skip to content

Instantly share code, notes, and snippets.

@gukandrew
Created January 8, 2025 18:38
Show Gist options
  • Save gukandrew/689666e909dbbacf32eaddc8cb07ab4a to your computer and use it in GitHub Desktop.
Save gukandrew/689666e909dbbacf32eaddc8cb07ab4a to your computer and use it in GitHub Desktop.
Vue 3 Composition API: Vee Validate 4 with zod or yup
<template>
<form @submit="onSubmit">
User Name:
<div>
<input v-model="name" class="border" v-bind="nameAttrs">
<span>{{ errors['user.name'] }}</span>
</div>
User Address:
<div>
<input v-model="address" class="border" v-bind="addressAttrs">
<span>{{ errors['user.address[0]'] }}</span>
</div>
<table class="w-full border">
<thead>
<tr>
<th>id</th>
<th>Price</th>
<th>Count</th>
<th>Height</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(field, index) in fields" :key="field.key">
<td>{{ index + 1 }}</td>
<td>
<input v-model="field.value.price" class="border w-full">
<span>{{ errors[`items[${index}].price`] }}</span>
</td>
<td>
<input v-model="field.value.count" class="border w-full">
<span>{{ errors[`items[${index}].count`] }}</span>
</td>
<td>
<input v-model="field.value.height" class="border w-full">
<span>{{ errors[`items[${index}].height`] }}</span>
</td>
<td>
<button type="button" class="bg-red-500 text-white w-full" @click="remove(key)">
Remove
</button>
</td>
</tr>
</tbody>
</table>
<button>Submit</button>
{{ errors }}
</form>
</template>
<script setup>
import { useForm, useFieldArray } from 'vee-validate'
import * as yup from 'yup'
import { toTypedSchema } from '@vee-validate/yup'
// import zod from 'zod'
// import { toTypedSchema } from '@vee-validate/zod'
const typedSchema = toTypedSchema(yup.object({
user: yup.object({
name: yup.string().required(),
address: yup.array().of(yup.string().required()),
items: yup.array().of(yup.object({
price: yup.string().required(),
count: yup.string().required(),
height: yup.string().required(),
})),
}),
}))
// const typedSchema = toTypedSchema(zod.object({
// user: zod.object({
// name: zod.string().min(1),
// address: zod.array(zod.string().min(1)),
// items: zod.array(zod.object({
// price: zod.string().min(1),
// count: zod.string().min(1),
// height: zod.string().min(1),
// })),
// }),
// }))
const { handleSubmit, errors, defineField } = useForm({
initialValues: {
user: {
name: '',
items: [
{ price: '123 Fake St', count: '123 Fake St', height: '123 Fake St' },
{ price: '456 Phony Ave', count: '123 Fake St', height: '123 Fake St' },
],
},
},
validationSchema: typedSchema,
})
const [name, nameAttrs] = defineField('user.name')
const [address, addressAttrs] = defineField('user.address[0]')
const { fields } = useFieldArray('user.items')
const onSubmit = handleSubmit(values => {
alert(JSON.stringify(values, null, 2))
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment