Skip to content
favoroderaPublic

About

Vue Forms Without the Friction

Topics

Resources

Code of conduct

Contributing

Stars

21 stars

Watchers

0 watching

Forks

Repository files navigation

header

license stars Custom badge Playground badge badge

NotForm provides the form state, validation, field state, submission lifecycle, and dynamic array-field primitives for Vue 3 while you decide how the form looks and behaves. There are no opinionated inputs, styles, or UI components built into the core.

Validation is schema-driven supporting any Standard Schema compatible validator, state is reactive, and the API is designed for typed field paths and Vue's Composition API.

Packages

Package Description
notform Core Vue 3 form management and headless components
notform-nuxt Official Nuxt integration with auto-imports

Install

Vue 3

pnpm add notform

Nuxt

npx nuxi module add notform

Then install a Standard Schema-compatible validator, for example:

pnpm add zod

Basic Usage

Single Fields

<script setup lang="ts">
import { NotField, NotForm, NotMessage, useNotForm } from 'notform'
import { z } from 'zod'

const schema = z.object({
  email: z.email('Enter a valid email address'),
  name: z.string('Enter a valid name'),
})

const form = useNotForm({
  initialValues: {
    email: '',
    name: '',
  },
  onSubmit(values) {
    console.log('Submitted:', values)
  },
  schema,
})
</script>

<template>
  <NotForm
    :form="form"
    @submit="form.submit"
    @reset="form.reset()"
  >
    <NotField
      v-slot="{ events, path }"
      path="name"
    >
      <div>
        <label :for="path">Name</label>

        <input
          :id="path"
          v-model="form.values.name"
          v-bind="events"
          name="name"
          type="text"
          autocomplete="name"
        >

        <NotMessage :path="path" />
      </div>
    </NotField>

    <NotField
      v-slot="{ events, path }"
      path="email"
    >
      <div>
        <label :for="path">Email address</label>

        <input
          :id="path"
          v-model="form.values.email"
          v-bind="events"
          name="email"
          type="email"
          autocomplete="email"
        >

        <NotMessage :path="path" />
      </div>
    </NotField>

    <button type="submit">
      Submit
    </button>

    <button type="reset">
      Reset
    </button>
  </NotForm>
</template>

Array Fields

NotArrayField provides renderless operations for dynamic arrays while preserving stable item keys during reordering.

<script setup lang="ts">
import { NotArrayField, NotField, NotForm, NotMessage, useNotForm } from 'notform'
import { z } from 'zod'

const tagSchema = z.string()

const schema = z.object({
  tags: z.array(tagSchema).optional(),
})

const form = useNotForm({
  initialValues: {
    tags: [''],
  },
  onSubmit(values) {
    console.log('Submitted:', values)
  },
  schema,
})
</script>

<template>
  <NotForm
    :form="form"
    @submit="form.submit"
    @reset="form.reset()"
  >
    <NotArrayField
      v-slot="{ items, append, remove }"
      path="tags"
      :item-schema="tagSchema"
    >
      <div
        v-for="(item, index) in items"
        :key="item.key"
      >
        <NotField
          v-slot="{ events, path }"
          :path="item.path"
        >
          <label :for="path">Tag {{ index + 1 }}</label>

          <input
            :id="path"
            v-model="form.values.tags[index]"
            v-bind="events"
            :name="path"
            type="text"
          >

          <NotMessage :path="path" />
        </NotField>

        <button
          type="button"
          @click="remove(index)"
        >
          Remove
        </button>
      </div>

      <button
        type="button"
        @click="append('')"
      >
        Add tag
      </button>
    </NotArrayField>
  </NotForm>
</template>

Development

This repository is a pnpm workspace managed with Turborepo.

pnpm install
pnpm dev

Common checks:

pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm ready

License

MIT © Favour Emeka

About

Vue Forms Without the Friction

Topics

Resources

Code of conduct

Contributing

Stars

21 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages