Discussion: Form Validations
caio-emidio opened this issue · comments
I was looking the maz-ui and looks awesome!
The only thing then i have some questions is about how is the best way to create a validation to one form.
How you normally do it?
Thanks
Hi @caio-emidio,
Thanks !
For me, the best way is to use vee-validate@4
with Composition API: https://vee-validate.logaretm.com/v4/guide/composition-api/getting-started/
All components are compatible with this library.
Example:
After installing the plugins and rules
Use
<form />
tag to keep a good accessibility
<template>
<form @submit.prevent="submitLogin">
<MazInput
id="username"
v-model="username"
name="username"
:error="!!usernameError"
auto-focus
:hint="usernameError"
autocomplete="username"
class="username-input"
no-radius
label="E-mail or username"
/>
<MazInput
id="password"
v-model="password"
name="current-password"
autocomplete="current-password"
type="password"
:error="!!passwordError"
:hint="passwordError"
no-radius
class="password-input"
label="Password"
/>
<MazBtn :loading="isSubmitting" :disabled="!isValidForm" block type="submit" class="maz-mt-8">
Log in
</MazBtn>
</form>
</template>
<script lang="ts" setup>
import { useAuth } from '~/composables/use-auth'
import { useIsFormValid, useForm, useField } from 'vee-validate'
const { handleSubmit, isSubmitting } = useForm()
const isValidForm = useIsFormValid()
const { login } = useAuth()
const { value: username, errorMessage: usernameError } = useField<string>('username', 'required|min:3', {
label: "e-mail or username",
})
const { value: password, errorMessage: passwordError } = useField<string>('password', 'required', {
label: 'password',
})
const submitLogin = handleSubmit(async (payload) => {
try {
// submit call
await login(payload)
// change route
} catch (error: any) {
// handle error
}
})
</script>
instead of using vee-validate's rules and useField
, you can use yup
or zod
to have a better Typescript support
Thanks!
if anyone needs... that was my example after some tests
<template>
<form class="flex flex-col gap-2" @submit.prevent="submitLogin">
<MazInput
id="username"
v-model="username"
name="username"
:error="!!usernameError"
auto-focus
:hint="usernameError"
autocomplete="username"
label="E-mail or username"
/>
<MazInput
id="password"
v-model="password"
name="current-password"
autocomplete="current-password"
type="password"
:error="!!passwordError"
:hint="passwordError"
label="Password"
/>
<MazBtn
:loading="isSubmitting"
:disabled="!isValidForm"
block
type="submit"
>
Log in
</MazBtn>
</form>
</template>
<script lang="ts" setup>
import { useIsFormValid, useForm, useField } from "vee-validate";
const { handleSubmit, isSubmitting } = useForm();
const isValidForm = useIsFormValid();
import * as yup from "yup";
const { value: username, errorMessage: usernameError } = useField<string>(
"username",
yup.string().email().required("Username is required")
);
const { value: password, errorMessage: passwordError } = useField<string>(
"password",
yup
.string()
.required("Password is required")
.min(6, "Password must be at least 6 characters")
);
const submitLogin = handleSubmit(async () => {
try {
authLogin({
username: username.value,
password: password.value,
});
} catch (error: any) {
toast().error(error.message);
}
});
</script>