π― ΠΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΡ β
Π£ΡΠ»ΠΎΠ²Π½Π°Ρ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΡ β
typescript
createForm({ type: '', companyName: '' }, (r, define) =>
define({
type: r.required().oneOf(['personal', 'business']),
companyName: r.requiredIf('type', 'business'),
})
)ΠΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ β
typescript
createForm({ username: '' }, (r, define) =>
define({
username: r
.required()
.minLength(3)
.remote(
async name => !(await fetch(`/api/users/${name}`)).ok,
'ΠΠΌΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΆΠ΅ Π·Π°Π½ΡΡΠΎ'
),
})
)ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° Π΄Π°Ρ β
typescript
createForm({ startDate: '', endDate: '' }, (r, define) =>
define({
startDate: r.required(),
endDate: r.required().dateAfter('startDate'),
})
)Π£Π½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½Π°Ρ ΡΠΎΡΠΌΠ° Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ β
ΠΠ΄Π½Π° ΠΈ ΡΠ° ΠΆΠ΅ ΡΠΎΡΠΌΠ° Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΠ»ΡΡΠ΅Π²ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ β ΠΏΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ Π΄Π°Π½Π½ΡΡ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ reset(), Π° Π½Π΅ setValues(), ΡΡΠΎΠ±Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ baseline ΠΈ isDirty ΠΎΡΡΠ°Π²Π°Π»ΡΡ false.
vue
<script setup lang="ts">
import { onMounted, computed } from 'vue'
import { createForm } from '@sakhnovkrg/vue-form-validator'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const userId = computed(() =>
route.params.id ? Number(route.params.id) : null
)
const isEditMode = computed(() => !!userId.value)
const form = createForm(
{
name: '',
email: '',
avatar: null as File | null,
},
(r, define) =>
define({
name: r.required().minLength(2),
email: r.required().email(),
avatar: [
r.fileType(['.jpg', '.jpeg', '.png']),
r.fileSize(3 * 1024 * 1024),
],
}),
{
async onSubmit(values) {
const formData = new FormData()
formData.append('name', values.name)
formData.append('email', values.email)
if (values.avatar) formData.append('avatar', values.avatar)
const url = isEditMode.value ? `/api/users/${userId.value}` : '/api/users'
const method = isEditMode.value ? 'PUT' : 'POST'
const response = await fetch(url, { method, body: formData })
if (!response.ok) {
const data = await response.json()
form.setErrors(data.fieldErrors)
return
}
const userData = await response.json()
if (!isEditMode.value) {
await router.push(`/users/${userData.id}/edit`)
}
},
}
)
// ΠΠ°Π³ΡΡΠ·ΠΊΠ° Π΄Π°Π½Π½ΡΡ
: reset() ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ baseline, ΡΠΎΡΠΌΠ° ΠΎΡΡΠ°ΡΡΡΡ ΡΠΈΡΡΠΎΠΉ
onMounted(async () => {
if (userId.value) {
const { name, email } = await fetch(`/api/users/${userId.value}`).then(r =>
r.json()
)
form.reset({ name, email })
}
})
</script>
<template>
<form @submit.prevent="form.submit">
<input
v-model="form.values.name"
@blur="form.touch('name')"
placeholder="ΠΠΌΡ"
/>
<span v-if="form.hasError('name')">{{ form.error('name') }}</span>
<input
v-model="form.values.email"
@blur="form.touch('email')"
placeholder="Email"
/>
<span v-if="form.hasError('email')">{{ form.error('email') }}</span>
<input type="file" @change="form.file.avatar.handler" />
<button
type="submit"
:disabled="!form.isDirty || !form.isValid || form.isSubmitting"
>
{{
form.isSubmitting
? 'Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅...'
: isEditMode
? 'Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ'
: 'Π‘ΠΎΠ·Π΄Π°ΡΡ'
}}
</button>
</form>
</template>Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ ΠΏΠΎΠ»ΡΠΌ β
typescript
const form = createForm({ username: '', email: '' }, (r, define) =>
define({
username: r.required().minLength(3),
email: r.required().email(),
})
)
// Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π΄Π»Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ
form.setErrors({ username: ['ΠΡΠΎ ΠΈΠΌΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΆΠ΅ Π·Π°Π½ΡΡΠΎ'] })
// Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ Π΄Π»Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
ΠΏΠΎΠ»Π΅ΠΉ
form.setErrors({
username: ['ΠΠ΅Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠ΅ ΡΠΈΠΌΠ²ΠΎΠ»Ρ Π² ΠΈΠΌΠ΅Π½ΠΈ'],
email: ['Email ΡΠΆΠ΅ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½', 'ΠΠ΅Π²Π΅ΡΠ½ΡΠΉ ΡΠΎΡΠΌΠ°Ρ email'],
})
// ΠΡΠΈΡΡΠΈΡΡ Π²ΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ
form.resetErrors()
// ΠΡΠΎΠ²Π΅ΡΠΈΡΡ Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ
if (form.hasError('username')) {
console.log(form.error('username')) // ΠΠ΅ΡΠ²Π°Ρ ΠΎΡΠΈΠ±ΠΊΠ°
console.log(form.allErrors('username')) // ΠΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΏΠΎΠ»Ρ
}Π’ΠΈΠΏΠΈΡΠ½ΡΠΉ ΠΏΠ°ΡΡΠ΅ΡΠ½ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΡ
ΠΎΡΠΈΠ±ΠΎΠΊ β Π²Π½ΡΡΡΠΈ onSubmit:
typescript
const form = createForm(
{ email: '', username: '' },
(r, define) =>
define({ email: r.required().email(), username: r.required() }),
{
async onSubmit(values) {
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
})
if (!res.ok) {
// Π‘Π΅ΡΠ²Π΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ: { fieldErrors: { email: ['Π£ΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ'] } }
const { fieldErrors } = await res.json()
if (fieldErrors) form.setErrors(fieldErrors)
return
}
console.log('Π‘ΠΎΠ·Π΄Π°Π½:', await res.json())
},
}
)