Integrations

Validation Libraries

Use validation libraries to validate your forms.

If you want to do more complex client side validation, or if you want to re-use validation logic on the client and the server, you can combine this module with your favourite validation libraries.

Vorms and Zod

In this example, we will use vorms to handle the client side validation, and zod for the schema definition.

pages/login.vue
<script setup lang="ts">
import { useForm } from "@vorms/core"
import { zodResolver } from "@vorms/resolvers/zod"
import z from "zod"

const { register, errors, validateForm } = useForm({
  initialValues: {
    account: "",
    password: "",
    remember: false
  },
  validate: zodResolver(
    z.object({
      account: z.string().min(1, "Account is required!"),
      password: z.string().min(1, "Password is required!")
    })
  ),
  onSubmit() {
    // Since we handle the form submission with the run function, this
    // isn't needed. However you can use it and submit the form manually
    // by calling vorms handleSubmit(event) within the run function.
  }
})

const { enhance } = await useFormAction({
  run: async ({ cancel, submitForm }) => {
    cancel() // Cancel the default form submission
    const result = await validateForm() // Validate with the library
    if (Object.keys(result).length === 0) { // Vorms returns an empty object if the form is valid.
      await submitForm() // Submit the form if valid ...
    }
  }
})

const { value: account, attrs: accountAttrs } = register("account", {
  validate(value) {
    if (!value) return "Account is required!"
  }
})
const { value: password, attrs: passwordAttrs } = register("password")
const { value: remember, attrs: rememberAttrs } = register("remember")
</script>

<template>
  <form v-enhance="enhance">
    <div class="field">
      <input
        v-model="account"
        class="field__input"
        type="text"
        placeholder="Account"
        v-bind="accountAttrs"
      >
      <div v-show="'account' in errors" class="field__error">
        {{ errors.account }}
      </div>
    </div>
    <div class="field">
      <input
        v-model="password"
        class="field__input"
        type="password"
        placeholder="Password"
        v-bind="passwordAttrs"
      >
      <div v-show="'password' in errors" class="field__error">
        {{ errors.password }}
      </div>
    </div>

    <div class="field checkbox">
      <input
        id="remember"
        v-model="remember"
        class="field__checkbox"
        type="checkbox"
        v-bind="rememberAttrs"
      >
      <label for="remember">remember</label>
    </div>

    <div class="field">
      <input type="submit">
    </div>
  </form>
</template>

Refer to the vorms-zod template to see it in action.