vue-tiny-validate

website·Indexed 29 days ago

https://vue-tiny-validate.js.org/

A tiny Vue composition API for data validation. It provides a useValidate hook to handle validation rules, nested data, and result states such as $invalid and $dirty.

Tokens
3.2K
Snippets
19
Records
24
Agent score
48%

What's inside vue-tiny-validate

  1. Overview of vue-tiny-validate features

    vue-tiny-validate is a tiny Vue validation composition library designed to be a robust and minimal alternative to larger libraries like Vuelidate or vee-validate.

    Key features include:

    • Minimal Size: Approximately 3.4KB minified and 1.4KB gzipped.
    • Compatibility: Works with both Vue 2.6 and Vue 3.
    • Validation Support: Supports both synchronous and asynchronous validation.
    • Reliability: Maintains nearly 100% unit test coverage.
  2. Understand why vue-tiny-validate requires custom validators

    vue-tiny-validate does not provide built-in validators because the library is designed to be flexible. Users are expected to build their own validators to ensure all specific project needs are satisfied without redundant pre-built logic.
  3. Configure dynamic validation messages and tests

    You can create dynamic validators or messages using higher-order functions. To include the current data value in a message, pass a function to the message property that accepts the value as an argument.
    // Dynamic Test (Higher Order Function)
    const rgxCheck = rgx => value => rgx.test(value);
    
    // Dynamic Message (Function receiving value)
    const rules = reactive({
      name: {
        name: 'required',
        test: rgxCheck(/^[0-9]{5}$/),
        message: value => `Your "${value}" is not allowed.`,
      },
    });
  4. Validate nested and array data structures

    vue-tiny-validate supports nested objects and arrays. For both, the rules object must mirror the structure of the data object. For arrays, rules are defined using the index as the key.
    // Nested Data
    const data = reactive({
      name: 'Evelyn',
      add: { street: 'St Louis' },
    });
    const rules = reactive({
      name: { name: 'required', test: v => Boolean(v), message: '...' },
      add: {
        street: { name: 'required', test: v => Boolean(v), message: '...' },
      },
    });
    
    // Array Data
    const dataArray = reactive({
      add: ['St Louis'],
    });
    const rulesArray = reactive({
      add: {
        0: { name: 'required', test: v => Boolean(v), message: '...' },
      },
    });
  5. Implement asynchronous validation

    Async validation is supported by default. Assign an async function or a function that returns a Promise to the test property of a validator.
    const rules = reactive({
      name: {
        name: 'required',
        test: async (value) => {
          const r = await someAsyncCheck(value);
          return r;
        }
      }
    });
  6. Implement basic data validation with useValidate

    The useValidate composition function provides a way to validate reactive data. It requires three parameters: data (mandatory), rules (mandatory), and options (optional). All three must be reactive objects (Ref, Reactive, or Computed). The data and rules objects must share the same property structure at every level. Validation is triggered by calling the result.$test method, and the validation state is stored in the result object.
    <template>
      <input v-model="data.name" />
      <div>Is Invalid: {{ result.$invalid }}</div>
      <div v-if="result.$messages.length">
        <span v-for="(message, index) in result.$messages" :key="index">
          {{ message }}
        </span>
      </div>
      <button v-on:click='result.$test'>Validate</button>
    </template>
    
    <script>
    import { reactive } from 'vue';
    import useValidate from 'vue-tiny-validate';
    
    export default {
      setup() {
        const data = reactive({ name: 'Evelyn' });
        const rules = reactive({
          name: {
            name: 'required',
            test: (value) => Boolean(value),
            message: 'Name must not be empty.'
          }
        });
        const options = reactive({});
        const { result } = useValidate(data, rules, options);
        return { result, data };
      }
    }
    </script>
  7. Understand reactivity requirements for parameters in vue-tiny-validate

    All parameters in vue-tiny-validate must be reactive objects. This design allows the library to use Vue's watch method to track changes to the parameters effortlessly.
  8. Define data and validation rules for vue-tiny-validate

    To use vue-tiny-validate, you must provide a Data object and a Rules object. Both must be reactive (Ref, Reactive, or Computed). The Data object must contain all properties defined in the Rules object, and both should share the same structure.

    • Data: A record of key-value pairs representing the form state.
    • Rules: A record where keys map to a single Rule, an array of Rule objects, or nested Rules for grouped data.
    type Data = Record<string, any>;
    
    interface Rule {
      test: ((value: any) => boolean) | ((value: any) => Promise<boolean>);
      message?: string | ((value: any) => string);
      name: string;
    }
    
    interface Rules {
      [key: string]: Array<Rule> | Rule | Rules;
    }
  9. Troubleshoot validation resets when re-assigning rules or options

    Re-assigning values to rules or options reactive objects will cause validation results to reset. This happens because the library uses watch with shallow comparison; re-assigning the object triggers the watch callback, which re-initializes the validation process.
  10. Understand the validation Result object

    The validation process produces a Result object that tracks the state of the validated properties. This object includes the following properties:

    • $invalid (boolean): True if any properties have errors.
    • $errors (Array<Error>): A list of error objects, each containing a name and an optional message.
    • $messages (Array<string>): A flat list of all error messages.
    • $dirty (boolean): True if the property value has changed or the $touch method was called.
    • $pending (boolean): True while an asynchronous validation is being performed by $test.
    interface Result {
      $invalid: boolean;
      $errors: Array<Error>;
      $messages: Array<string>;
      $dirty: boolean;
      $pending: boolean;
    }
    
    interface Error {
      name: string;
      message?: string | null;
    }
  11. Manually trigger validation with $test

    Use the $test method to manually trigger validation. You can call it on the root result object to validate all properties, or on a specific property to validate only that field. Note: $test is a method of the result object and is distinct from the test function used within a validator.
    const { result } = useValidate(data, rules);
    
    // Test all properties
    const testAll = () => {
      result.value.$test();
    };
    
    // Test only the 'name' property
    const testName = () => {
      result.value.name.$test();
    };