Components
@vuetils/form
comes with two helper components UField
and UForm
that make it easier to create forms. These components handle the two-way data binding and add validation classes to the inputs and the form
element so differnt form states can be styled with CSS.
UField
UField
is the basic building block of a form. It is a wrapper around the native label
element and can be used in the exact same way. UField
needs exactly one input
element as a slot and can have optional label content too. The label content can either be just plain text like in the example below or any other Vue components or HTML elements.
If used outside a UForm
component UField
needs a Field
instance as a prop.
Validation Classes
Depending on the validation state of the Field
instance these classes are added to the input
element:
v-valid
- added when the field is validv-invalid
- added when the field is invalidv-pristine
- added when the field's value has not been changed yetv-dirty
- added when the field's value has been changedv-pending
- added when the field hasasync validators
that are being resolvedv-touched
- added when the field has been blurred yetv-untouched
- added when the field hasn't been blurred yet
There are also the classes v-label
and v-input
that are added to the label
and input
elements respectively. Play around with the example and see how different classes get added or removed.
Example
<template>
<UField :field="field">
Label:
<input name="field" type="text" required />
</UField>
</template>
<script setup>
import { UField, required, useField } from '@vuetils/form';
const field = useField('', { validators: [required] });
</script>
Markup
This will create the following clean and minimal HTML markup
// model value:
<label class="v-label">
Label:
<input
name="field"
type="text"
required
class="v-invalid v-pristine v-untouched v-input"
/>
</label>
UForm
UForm
is a wrapper around the native form
element and can be used in the exact same way. UForm
needs UField
components as child slots. The name attribute of the input
element is used to bind the input to the matching Field
instance.
Validation Classes
Similar how it works with UField
these classes are added depending on the validation state of the Form
instance:
v-valid
- added when all fields are validv-invalid
- added when on ore more fields are invalidv-pristine
- added when all fields are pristinev-dirty
- added when one or more fields are dirtyv-pending
- added when one or more fields are pendingv-submitted
- added when the form has been submitted no matter if it was valid or notv-touched
- added when one or more fields have been blurredv-untouched
- added when no fields haven been blurred
There is also the class v-form
that is added to the form
element. Play around with the example and see how differnt classes get added or removed.
Example
<template>
<UForm :form="form">
<UField>
Firstname:
<input name="firstname" type="text" required />
</UField>
<UField>
Lastname:
<input name="lastname" type="text" required />
</UField>
<button>Submit</button>
</UForm>
</template>
<script setup>
import { UField, UForm, required, useForm } from '@vuetils/form';
const form = useForm({
firstname: ['', [required]],
lastname: ['', [required]],
});
</script>
Markup
This will create the following clean and minimal HTML markup
<form class="v-invalid v-pristine v-untouched v-form">
// model value:
<label class="v-label">
Email:
<input
name="firstname"
type="firstname"
required
class="v-invalid v-pristine v-untouched v-input"
/>
</label>
// model value:
<label class="v-label">
Password:
<input
name="lastname"
type="lastname"
required
class="v-invalid v-pristine v-untouched v-input"
/>
</label>
<button>Submit</button>
</form>
Submit event
UForm
emits the custom event v-submit
every time the form is submitted. The event handler receives the current values of the form. This can also be typed with typeof form.values
as shown in the example below.
If you want to you can also just listen to the native submit
event.
<template>
<UForm :form="form" v-submit="onSubmit">
<!-- Form inputs -->
</UForm>
</template>
<script setup lang="ts">
import { UForm, useForm } from '@vuetils/form';
const form = useForm({
firstname: [''],
lastname: [''],
});
function onSubmit(values: typeof form.values) {
if (form.invalid) {
//handle errors
}
// do something with the values
}
</script>