Vuetils Form

website·Indexed 30 days ago

https://form.vuetils.dev/

A lightweight and simple-to-use form validation library for Vue. It features a small bundle size (less than 5KB minified), the useForm composable, helper components like UField and UForm, and a plugin system to extend functionality.

Tokens
4.2K
Snippets
25
Records
36
Agent score
50%

What's inside Vuetils Form

  1. Extend @vuetils/form functionality using plugins

    Plugins in @vuetils/form provide access to the entire Form instance, allowing developers to implement cross-cutting concerns such as watching for value changes, persisting form state to a database or local storage, manipulating form state, or dynamically enabling/disabling form fields.
  2. Integrate Zod and Valibot validators

    Starting from v0.2.2, the library includes built-in support for Zod and Valibot validators to simplify schema-based validation.
  3. Use custom input components and native HTML validation

    As of v0.2.7, the library supports custom input components. These components now explicitly bind host attributes and support native HTML validation attributes.
  4. Add plugins to a form

    Plugins can be integrated into a form using two methods: passing them during initialization via useForm() or adding them dynamically using the addPlugin() method on the form instance.
    import { localStoragePlugin, useForm } from '@vuetils/form';
    
    // Option 1: Pass to useForm during initialization
    const form = useForm(
    	{
    		email: [''],
    		password: [''],
    	},
    	{
    		plugins: [localStoragePlugin('some-key')],
    	}
    );
    
    // Option 2: Add dynamically
    const formDynamic = useForm({
    	email: [''],
    	password: [''],
    });
    formDynamic.addPlugin(localStoragePlugin('some-key'));
  5. Manage multiple form fields with useForm

    useForm is the core composable for grouping multiple input elements. It creates a Field instance for every property defined in the configuration object. The configuration object keys correspond to the input names, and the values are arrays following the pattern: [initialValue, syncValidators[], asyncValidators[]].
    import { defineValidator, useForm } from '@vuetils/form';
    
    const syncValidator = defineValidator('sync', (value) => true);
    const asyncValidator = defineValidator('async', async (value) => true);
    
    const form = useForm({
    	hallo: ['initialValue', [syncValidator], [asyncValidator]],
    	zwallo: [0], // Only initial value provided
    	drallo: [false, [], [asyncValidator]], // Initial value and async validators
    });
  6. Configure form-wide synchronous validators

    v0.2.5 added support for form-wide synchronous validators, enabling validation logic that depends on multiple fields across the entire form.
  7. Implement HTML validation attributes in @vuetils/form

    To leverage native browser validation alongside JavaScript validation, @vuetils/form provides built-in equivalents for standard HTML validation attributes. When used with UField or UForm components, these attributes are automatically added to the input elements. Supported attributes include:

    • required: Field must be filled.
    • minlength and maxlength: Constraints on string length.
    • min and max: Constraints on numeric values.
  8. Initialize a form with useForm

    Use the useForm() function to create a form instance. The function accepts a configuration object where each key represents an input element's name. The value for each key must be an array containing two elements: the initial value of the input and an array of validators.
    <script setup>
    import { useForm, required, email, minLength } from '@vuetils/form';
    
    const form = useForm({
    	email: ['', [required, email]],
    	password: ['', [required, minLength(6)]],
    });
    </script>
  9. Implement asynchronous validators

    Async validators function similarly to synchronous validators but return a Promise<boolean> instead of a boolean. In useForm or useField, async validators are passed in a separate configuration array to distinguish them from synchronous checks.
    import { defineValidator, useField, useForm } from '@vuetils/form';
    
    const syncValidator = defineValidator('sync', (value) => true);
    const asyncValidator = defineValidator('async', async (value) => true);
    
    // In useForm: [initialValue, syncValidators, asyncValidators]
    const form = useForm({
    	field: ['', [syncValidator], [asyncValidator]],
    });
    
    // In useField: separate validators and asyncValidators keys
    const field = useField('', {
    	validators: [syncValidator],
    	asyncValidators: [asyncValidator],
    });
  10. Manage a single input field with useField

    useField is used for standalone inputs. It accepts an initial value and an options object containing synchronous and asynchronous validators. It exposes state properties (valid, invalid, enabled, disabled, pristine, dirty, async, pending) and control methods.
    import { defineValidator, useField } from '@vuetils/form';
    
    const syncValidator = defineValidator('sync', (value) => true);
    const asyncValidator = defineValidator('async', async (value) => true);
    
    const field = useField('initialValue', {
    	validators: [syncValidator],
    	asyncValidators: [asyncValidator],
    });
    
    // Control methods
    field.reset();
    field.disable();
    field.enable();
    await field.awaitValidation();
    
    // State access
    console.log(field.pending); // true if async validator is running
  11. Use UForm to manage form state and binding

    UForm is a wrapper around the native form element. It requires UField components as child slots. The name attribute of the input elements inside UField is used to bind the input to the matching Field instance defined in the useForm configuration.
    <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>