kliping.pro
  • Docs
  • Explore
  • Builder
  • Directory
  • Colors
  • Typeset
Saved
Docs
  • Sections13
  • Installation5
  • Dark Mode4
  • Forms3
  • Registry6
  • Utilities2
  • More10
  • Components137
  • Accordion
  • Action Bar
  • AI Chat
  • AI Thread List
  • Alert
  • Alert Dialog
  • Angle Slider
  • Animated Grid Pattern
  • Aspect Ratio
  • Attachment
  • Avatar
  • Avatar Group
  • Badge
  • Badge Overflow
  • Banner
  • Border Beam
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Checkbox Group
  • Chip
  • Circular Progress
  • Client Only
  • Collapsible
  • Color Picker
  • Color Swatch
  • Combobox
  • Combobox Advanced
  • Command
  • Compare Slider
  • Composition
  • Context Menu
  • Cropper
  • Data Grid
  • Data Table
  • Data Table Advanced
  • Date Picker
  • Dialog
  • Direction Provider
  • Dot Pattern
  • Drawer
  • Dropdown Menu
  • Editable
  • Empty
  • Field
  • File Upload
  • Form
  • FPS
  • Gauge
  • Hitbox
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kanban
  • Kbd
  • Kbd Advanced
  • Key Value
  • Label
  • List
  • Listbox
  • Logos
  • Map
  • Marker
  • Marquee
  • Mask Input
  • Masonry
  • Media Player
  • Mention
  • Menubar
  • Message
  • Message Scroller
  • Native Select
  • Navigation Menu
  • Number Field
  • Pagination
  • Particles
  • Pending
  • Phone Input
  • Pin Input
  • Popover
  • Portal
  • Presence
  • Progress
  • QR Code
  • Questionnaire
  • Radio Group
  • Range Calendar
  • Rating
  • Relative Time Card
  • Resizable
  • Responsive Dialog
  • Scroll Area
  • Scroll Spy
  • Scroller
  • Segmented Input
  • Select
  • Selection Toolbar
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Software Purchase Card
  • Sonner
  • Sortable
  • Speed Dial
  • Spinner
  • Stack
  • Stat
  • Status
  • Stepper
  • Stepper Advanced
  • Swap
  • Switch
  • Table
  • Tabs
  • Tags Input
  • Tags Input Advanced
  • Textarea
  • Time Picker
  • Timeline
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip
  • Tour
  • Typography
  • Visually Hidden
  • Visually Hidden Input
  1. Docs
  2. Components
  3. Form

Form

PreviousNext

Membangun form memakai VeeValidate dan Zod.

We are not actively developing this component anymore.

Komponen Form adalah lapisan abstraksi di atas library vee-validate. Ke depannya, kami menyarankan Anda memakai komponen <Field /> untuk membangun form. Keterangan lengkapnya ada di dokumentasi Form.

Form itu rumit. Ia salah satu hal yang paling sering Anda bangun di aplikasi web, sekaligus salah satu yang paling ruwet.

Form HTML yang dirancang dengan baik punya ciri-ciri berikut:

  • Terstruktur rapi dan bermakna secara semantik.
  • Mudah dipakai dan dinavigasi, termasuk lewat keyboard.
  • Mudah diakses lewat atribut ARIA dan label yang benar.
  • Mendukung validasi di sisi klien maupun server.
  • Tampilannya rapi dan selaras dengan sisa aplikasi.

Di panduan ini kita akan membangun form memakai vee-validate dan zod. Komponen <FormField> akan kita pakai untuk menyusun form yang mudah diakses dari komponen Reka UI.

Features ​

Komponen <Form /> adalah pembungkus library vee-validate. Ia menyediakan beberapa hal:

  • Komponen yang bisa dikomposisikan untuk membangun form.
  • Komponen <FormField /> untuk membangun field yang nilainya dikendalikan.
  • Validasi form memakai zod.
  • Menerapkan atribut aria yang tepat pada tiap field sesuai keadaannya, sekaligus mengurus ID yang unik.
  • Dirancang agar bekerja dengan semua komponen Reka UI.
  • Bebas memilih library skema. Kami memakai zod, tapi Anda bisa memakai library validasi lain yang didukung, seperti yup atau valibot.
  • Markup dan style-nya sepenuhnya di tangan Anda.

vee-validate menyediakan dua gaya penulisan untuk menambahkan validasi ke form Anda.

  • Composition API
  • Higher-order component (HOC)

Anatomy ​

vue
<template>
  <Form>
    <FormField>
      <FormItem>
        <FormLabel />
        <FormControl>
        <!-- any Form Input component or native input elements -->
        </FormControl>
        <FormDescription />
        <FormMessage />
      </FormItem>
    </FormField>
  </Form>
</template>

Examples ​

Komponen Input ​

vue
<template>
  <FormField v-slot="{ componentField }">
    <FormItem>
      <FormLabel>Username</FormLabel>
      <FormControl>
        <Input placeholder="shadcn" v-bind="componentField" />
      </FormControl>
      <FormDescription />
      <FormMessage />
    </FormItem>
  </FormField>
</template>
1
2
3
4
5
6
7
8
9
10
11
12

Elemen input bawaan ​

vue
<template>
  <FormField v-slot="{ field }">
    <FormItem>
      <FormLabel>Username</FormLabel>
      <FormControl>
        <input placeholder="shadcn" v-bind="field">
      </FormControl>
      <FormDescription />
      <FormMessage />
    </FormItem>
  </FormField>
</template>
1
2
3
4
5
6
7
8
9
10
11
12

Installation ​

pnpm dlx kliping@latest add form

Pasang dependensi berikut:

pnpm add reka-ui vee-validate @vee-validate/zod zod

Salin dan tempel kode sumber di GitHub ke project Anda.

Sesuaikan path import dengan struktur project Anda.

Usage ​

vue
<script setup lang="ts">
import {
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
</script>

<template>
  <FormField v-slot="{ componentField }" name="username">
    <FormItem>
      <FormLabel>Username</FormLabel>
      <FormControl>
        <Input placeholder="shadcn" v-bind="componentField" />
      </FormControl>
      <FormDescription>
        This is your public display name.
      </FormDescription>
      <FormMessage />
    </FormItem>
  </FormField>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

Buat skema form ​

Tentukan bentuk form Anda memakai skema Zod. Penjelasan lengkap soal Zod ada di dokumentasi Zod.

Pakai @vee-validate/zod untuk menyambungkan validasi skema Zod dengan vee-validate.

toTypedSchema sekaligus membuat nilai form dan nilai yang dikirim bertipe otomatis, mencakup tipe masukan maupun keluaran skema tersebut.

vue
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'

const formSchema = toTypedSchema(z.object({
  username: z.string().min(2).max(50),
}))
</script>
1
2
3
4
5
6
7
8

Definisikan form ​

Buat form memakai composable useForm dari vee-validate, atau memakai komponen <Form />.

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

import {
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from '@/components/ui/form'

const formSchema = toTypedSchema(z.object({
  username: z.string().min(2).max(50),
}))

const form = useForm({
  validationSchema: formSchema,
})

const onSubmit = form.handleSubmit((values) => {
  console.log('Form submitted!', values)
})
</script>

<template>
  <form @submit="onSubmit">
    ...
  </form>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
vue
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from '@/components/ui/form'

const formSchema = toTypedSchema(z.object({
  username: z.string().min(2).max(50),
}))

function onSubmit(values) {
  console.log('Form submitted!', values)
}
</script>

<template>
  <Form :validation-schema="formSchema" @submit="onSubmit">
    ...
  </Form>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Susun form Anda ​

Melanjutkan langkah sebelumnya, Anda bisa memakai komponen <Form /> atau composable useForm. useForm lebih disarankan karena nilainya otomatis bertipe.

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

import { Button } from '@/components/ui/button'
import {
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'

const formSchema = toTypedSchema(z.object({
  username: z.string().min(2).max(50),
}))

const form = useForm({
  validationSchema: formSchema,
})

const onSubmit = form.handleSubmit((values) => {
  console.log('Form submitted!', values)
})
</script>

<template>
  <form @submit="onSubmit">
    <FormField v-slot="{ componentField }" name="username">
      <FormItem>
        <FormLabel>Username</FormLabel>
        <FormControl>
          <Input type="text" placeholder="shadcn" v-bind="componentField" />
        </FormControl>
        <FormDescription>
          This is your public display name.
        </FormDescription>
        <FormMessage />
      </FormItem>
    </FormField>
    <Button type="submit">
      Submit
    </Button>
  </form>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

Selesai ​

Selesai. Sekarang Anda punya form yang mudah diakses, aman secara tipe, dan tervalidasi di sisi klien.

This is your public display name.

Requirements ​

Semua dipasang otomatis oleh kliping add; tabel ini untuk Anda yang memasang manual atau memeriksa project.

RequirementValue
ProjectVue 3.5+, Tailwind CSS v4, alias @ — disiapkan kliping init
npm packagesreka-ui@^2.10.3, vee-validate@^4.15.1
Kliping itemslabel
Filescomponents/ui/form/form-control.vue
components/ui/form/form-description.vue
components/ui/form/form-item.vue
components/ui/form/form-label.vue
components/ui/form/form-message.vue
components/ui/form/index.ts
components/ui/form/injection-keys.ts
components/ui/form/use-form-field.ts

Anatomy ​

Susunan bagiannya seperti dipakai di contoh-contoh di atas. Impor semua bagian dari satu tempat, lalu susun begini:

vue
<FormItem>
  <FormLabel />
  <FormControl />
  <FormDescription />
  <FormMessage />
</FormItem>

API Reference ​

FormControl ​

SlotProps
#default—
Data attributeValue
[data-slot]"form-control"

FormDescription ​

SlotProps
#default—
Data attributeValue
[data-slot]"form-description"

FormItem ​

SlotProps
#default—
Data attributeValue
[data-slot]"form-item"

FormLabel ​

PropTypeDefaultDescription
for?string—The id of the element the label is associated with.
asChild?boolean—Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.
as?AsTag | Component—The element or component this component should render as. Can be overwritten by asChild.
SlotProps
#default—
Data attributeValue
[data-slot]"form-label"
[data-error]set at runtime

FormMessage ​

Data attributeValue
[data-slot]"form-message"

CSS Variables ​

Token tema yang dibaca komponen ini — ubah nilainya di CSS global (:root dan .dark, lihat Theming) untuk mengubah tampilannya tanpa menyentuh komponennya: --destructive, --muted-foreground.

Credits ​

Berasal dari shadcn-vue (MIT, Copyright (c) 2023 unovue). Rantai lengkapnya di Credits.

PreviousFile UploadNext FPS

On This Page

FeaturesAnatomyExamplesInstallationUsageBuat skema formDefinisikan formSusun form AndaSelesaiRequirementsAnatomyAPI ReferenceFormControlFormDescriptionFormItemFormLabelFormMessageCSS VariablesCredits

© 2026 Kliping. Free components are open source under the MIT License.

LicenseCreditsRoadmap