Skip to content

/web-forms-vee-validate

VeeValidate v4 patterns - useForm, useField, defineField, useFieldArray, schema validation with Composition API

shell
$ npx -y skills add agents-inc/skills --skill web-forms-vee-validate --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-forms-vee-validate
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

VeeValidate v4 patterns - useForm, useField, defineField, useFieldArray, schema validation with Composition API

SKILL.md

web-forms-vee-validate.SKILL.md
name: web-forms-vee-validate
description: VeeValidate v4 patterns - useForm, useField, defineField, useFieldArray, schema validation with Composition API

VeeValidate Form Validation Patterns

> **Quick Guide:** Use VeeValidate v4 for Vue 3 form validation with Composition API. Use `useForm` for form state, `defineField` for quick field setup, `useField` for custom input components, and `useFieldArray` for dynamic lists. Always wrap schema libraries with `toTypedSchema()`. Always use `field.key` (not index) as iteration key in field arrays.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST use `toTypedSchema()` wrapper when using schema libraries in v4 - raw schemas won't work)**

**(You MUST use `field.key` as iteration key in useFieldArray - NEVER use array index)**

**(You MUST use function form `() => props.name` or `toRef()` in useField for prop reactivity)**

**(You MUST initialize field array values in `initialValues` - undefined arrays cause errors)**

</critical_requirements>

---

**Auto-detection:** VeeValidate, vee-validate, useForm, useField, defineField, useFieldArray, toTypedSchema, ErrorMessage, Form component

**When to use:**

  • Building Vue 3 forms with validation requirements
  • Managing complex form state with multiple fields
  • Creating dynamic forms with add/remove field capabilities
  • Integrating schema validation libraries with `toTypedSchema()`
  • Building multi-step wizard forms

**When NOT to use:**

  • Single input without validation (use native v-model)
  • Server-only forms with server actions (use native form submission)
  • Read-only data display (not a form scenario)

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - defineField, useField, form meta, eager validation
  • [examples/validation.md](examples/validation.md) - Zod/Yup/Valibot schema integration, conditional validation
  • [examples/arrays.md](examples/arrays.md) - useFieldArray, nested arrays, reordering
  • [reference.md](reference.md) - Decision frameworks, API reference tables, anti-patterns

---

<philosophy>

Philosophy

VeeValidate v4 embraces Vue 3's Composition API as the primary approach, enabling seamless integration with any UI library. Validation logic is decoupled from presentation, allowing schema-first validation with full TypeScript inference.

**Core Principles:**

1. **Composition API first** - Use `useForm`, `useField`, `defineField` for seamless Vue 3 integration 2. **Schema-first validation** - Prefer declarative schemas over inline rules 3. **Full type safety** - TypeScript inference from schemas and generics 4. **UI agnostic** - Works with any component library or native inputs 5. **Minimal re-renders** - Efficient reactivity through Vue's reactive system

**defineField vs useField:**

| Feature | `defineField` | `useField` | | ---------------- | ----------------------------------- | ----------------------------------------- | | **Use case** | Quick form setup with native inputs | Building reusable custom input components | | **Form context** | Always requires form context | Optional form integration | | **Best for** | Application-level forms | Component library development |

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Basic Form with defineField

Use `useForm` with `defineField` for the fastest form setup. `defineField` returns a `[model, attrs]` tuple for v-model binding. See [examples/core.md](examples/core.md) for full examples.

<script setup lang="ts">
import { useForm } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import { z } from "zod";

const schema = toTypedSchema(
  z.object({
    email: z.string().email("Invalid email"),
    password: z.string().min(8, "At least 8 characters"),
  }),
);

const { handleSubmit, errors, defineField } = useForm({
  validationSchema: schema,
});

const [email, emailAttrs] = defineField("email");

const onSubmit = handleSubmit((values) => {
  // values is fully typed from schema
});
</script>

---

Pattern 2: Custom Input Components with useField

Use `useField` when building reusable input components. **Critical:** use function form `() => props.name` to maintain reactivity. See [examples/core.md](examples/core.md) for full component example.

<script setup lang="ts">
import { useField } from "vee-validate";

const props = defineProps<{ name: string }>();

// CRITICAL: Function form maintains reactivity
const { value, errorMessage, handleBlur, meta } = useField<string>(
  () => props.name,
  undefined,
  { validateOnValueUpdate: false },
);
</script>

---

Pattern 3: Schema Validation with toTypedSchema

Always wrap schema libraries with `toTypedSchema()`. Initialize ALL fields used in `refine/superRefine` - Zod skips refinements when keys are undefined. See [examples/validation.md](examples/validation.md) for Zod, Yup, and Valibot examples.

import { toTypedSchema } from "@vee-validate/zod";

// CORRECT: Wrapped schema
const schema = toTypedSchema(z.object({ email: z.string().email() }));

// WRONG: Raw schema won't work with VeeValidate
const schema = z.object({ email: z.string().email() });

---

Pattern 4: Dynamic Arrays with useFieldArray

Use `useFieldArray` for add/remove/reorder patterns. **Always** use `field.key` as `:key`, never array index. Initialize arrays in `initialValues`. See [examples/arrays.md](examples/arrays.md) for full patterns.

<script setup lang="ts">
import { useForm, useFieldArray } from "vee-validate";

const { handleSubmit } = useForm({
  initialValues: { users: [{ name: "", email: "" }] },
});

const { fields, push, remove } = useFieldArray("users");
</script>

<template>
  <!-- CORRECT: field.key
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked