Skip to content

Form ​

Forma elementlari uchun joylashuv, tekshiruv va holatni boshqarish imkoniga ega forma wrapperi.

Optional short bio
vue
<script setup>
const formRef = ref()
const form = reactive({ name: '', email: '', bio: '' })

const rules = {
  name: [
    { required: true, message: 'Please enter your name' },
    { min: 2, max: 30, message: 'Name must be 2-30 characters' },
  ],
  email: [
    { required: true, message: 'Please enter your email' },
    { type: 'email', message: 'Please enter a valid email' },
  ],
}

async function onSubmit() {
  const { valid } = await formRef.value.validate()
  if (valid) { /* submit */ }
}
</script>

<template>
  <VxForm ref="formRef" :model="form" :rules="rules">
    <VxFormItem label="Name" field="name">
      <VxInput v-model="form.name" />
    </VxFormItem>
    <VxFormItem label="Email" field="email">
      <VxInput v-model="form.email" />
    </VxFormItem>
    <VxFormItem>
      <VxButton @click="onSubmit">Submit</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Horizontal Layout ​

vue
<template>
  <VxForm :model="form" :rules="rules" layout="horizontal" :label-width="120">
    <VxFormItem label="Username" field="username">
      <VxInput v-model="form.username" />
    </VxFormItem>
    <VxFormItem label="Password" field="password">
      <VxInput v-model="form.password" type="password" />
    </VxFormItem>
    <VxFormItem label=" ">
      <VxButton>Login</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Inline Layout ​

All
vue
<template>
  <VxForm :model="form" layout="inline">
    <VxFormItem label="Search">
      <VxInput v-model="form.search" />
    </VxFormItem>
    <VxFormItem label="Category">
      <VxSelect v-model="form.category" :options="options" />
    </VxFormItem>
    <VxFormItem>
      <VxButton>Search</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Label Description ​

Yorliq yonida ma'lumot ikonkasini tooltip bilan qo'shish uchun description prop dan yoki boyitilgan tarkib uchun #description slot dan foydalaning.

vue
<template>
  <!-- Simple text description -->
  <VxFormItem label="API Key" description="Your unique API key from the dashboard.">
    <VxInput v-model="form.apiKey" />
  </VxFormItem>

  <!-- Rich content via #description slot -->
  <VxFormItem label="Secret">
    <template #description>
      <div>
        <strong>Signing Secret</strong>
        <p>Used to verify webhook payloads.</p>
      </div>
    </template>
    <VxInput v-model="form.secret" type="password" />
  </VxFormItem>
</template>

Type Validators ​

O'rnatilgan tur validatorlari: email, url, number, integer, float, date, hex, ip, phone, alpha, alphanumeric, string, boolean, array.

vue
const rules = {
  email: [
    { required: true, message: 'Required' },
    { type: 'email', message: 'Invalid email format' },
  ],
  url: [{ type: 'url', message: 'Invalid URL' }],
  age: [
    { type: 'integer', message: 'Must be a whole number' },
    { min: 1, max: 150, message: 'Age must be 1-150' },
  ],
  ip: [{ type: 'ip', message: 'Invalid IP address' }],
  hex: [{ type: 'hex', message: 'Invalid hex color' }],
  phone: [{ type: 'phone', message: 'Invalid phone number' }],
}

String Constraints ​

Satr tekshiruvi uchun pattern, enum, startsWith, endsWith, contains va alpha/alphanumeric turlaridan foydalaning.

Format: XX-000 or XXX-0000
Letters and numbers only
Must start with #
Must end with .com
admin, editor, or viewer
vue
const rules = {
  code: [
    { required: true, message: 'Required' },
    { pattern: /^[A-Z]{2,3}-\d{3,4}$/, message: 'Format: XX-000 or XXX-0000' },
  ],
  slug: [
    { type: 'alphanumeric', message: 'Only letters and numbers' },
  ],
  tag: [
    { startsWith: '#', message: 'Must start with #' },
    { min: 2, message: 'At least 2 characters' },
  ],
  domain: [
    { endsWith: '.com', message: 'Must end with .com' },
  ],
  role: [
    { enum: ['admin', 'editor', 'viewer'], message: 'Must be admin, editor, or viewer' },
  ],
}

Cross-Field Validation ​

Maydonlarni solishtirish uchun same va different, substring tekshiruvi uchun contains dan foydalaning.

vue
const rules = {
  password: [
    { required: true, message: 'Password is required' },
    { min: 8, message: 'At least 8 characters' },
    { contains: '!', message: 'Must contain !' },
  ],
  confirm: [
    { required: true, message: 'Please confirm' },
    { same: 'password', message: 'Passwords do not match' },
  ],
  newEmail: [
    { required: true, message: 'New email is required' },
    { type: 'email', message: 'Invalid email' },
    { different: 'currentEmail', message: 'Must differ from current email' },
  ],
}

Async Validator ​

Validatorlar Promise qaytarishi mumkin. Foydalanuvchi nomining mavjudligi kabi server tomonidagi tekshiruvlar uchun foydali.

Try 'admin', 'root', or 'test'
vue
const rules = {
  username: [
    { required: true, message: 'Username is required' },
    { type: 'alpha', message: 'Letters only' },
    { min: 3, max: 20, message: '3-20 characters' },
    {
      validator: async (value) => {
        const taken = await checkUsername(value)
        if (taken) return 'Username is already taken'
        return true
      },
      trigger: 'blur',
    },
  ],
}

Reset & Clear Validation ​

vue
<script setup>
const formRef = ref()
</script>

<template>
  <VxForm ref="formRef" :model="form" :rules="rules">
    ...
    <VxButton @click="formRef.validate()">Validate</VxButton>
    <VxButton @click="formRef.clearValidation()">Clear Errors</VxButton>
    <VxButton @click="formRef.resetFields()">Reset</VxButton>
  </VxForm>
</template>

Disabled ​

vue
<template>
  <VxForm :model="form" disabled>
    <VxFormItem label="Name"><VxInput v-model="form.name" /></VxFormItem>
    <VxFormItem label="Email"><VxInput v-model="form.email" /></VxFormItem>
  </VxForm>
</template>

Horizontal Example ​

Select role
vue
<script setup>
const formRef = ref()
const form = reactive({
  firstName: '', lastName: '', email: '',
  role: '', newsletter: false, notes: '',
})

const rules = {
  firstName: { required: true, message: 'First name is required' },
  lastName: { required: true, message: 'Last name is required' },
  email: [
    { required: true, message: 'Email is required' },
    { type: 'email', message: 'Invalid email format' },
  ],
  role: { required: true, message: 'Please select a role' },
}
</script>

<template>
  <VxForm ref="formRef" :model="form" :rules="rules" layout="horizontal" :label-width="120">
    <VxFormItem label="First Name" field="firstName">
      <VxInput v-model="form.firstName" />
    </VxFormItem>
    <VxFormItem label="Role" field="role">
      <VxSelect v-model="form.role" :options="roles" />
    </VxFormItem>
    <VxFormItem label="Newsletter">
      <VxSwitch v-model="form.newsletter" />
    </VxFormItem>
    <VxFormItem label=" ">
      <VxButton @click="formRef.validate()">Submit</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Registration Form ​

Har bir maydon uchun bir nechta tekshiruv qoidalari, kuchli parol tekshiruvi, maydonlararo solishtirish va aralash kiritish turlariga ega to'liq misol.

Optional
HTTPS required
Select role
Max 200 characters
vue
<script setup>
const formRef = ref()
const form = reactive({
  name: '', email: '', password: '', confirmPassword: '',
  phone: '', website: '', role: '', bio: '', terms: false,
})

const rules = {
  name: [
    { required: true, message: 'Full name is required' },
    { min: 2, max: 50, message: '2-50 characters' },
    { type: 'alpha', message: 'Letters only' },
  ],
  email: [
    { required: true, message: 'Email is required' },
    { type: 'email', message: 'Enter a valid email address' },
  ],
  password: [
    { required: true, message: 'Password is required' },
    { min: 8, message: 'At least 8 characters' },
    {
      validator: (v) => {
        if (!/[A-Z]/.test(v)) return 'Must contain an uppercase letter'
        if (!/[0-9]/.test(v)) return 'Must contain a number'
        if (!/[^a-zA-Z0-9]/.test(v)) return 'Must contain a special character'
        return true
      },
    },
  ],
  confirmPassword: [
    { required: true, message: 'Confirm your password' },
    { same: 'password', message: 'Passwords do not match' },
  ],
  phone: [{ type: 'phone', message: 'Enter a valid phone number' }],
  website: [
    { type: 'url', message: 'Enter a valid URL' },
    { startsWith: 'https://', message: 'Must use HTTPS' },
  ],
  role: [
    { required: true, message: 'Select a role' },
  ],
  bio: [{ max: 200, message: 'Max 200 characters' }],
  terms: [
    { validator: (v) => v === true ? true : 'You must accept the terms' },
  ],
}
</script>

<template>
  <VxForm ref="formRef" :model="form" :rules="rules">
    <VxFormItem label="Full Name" field="name">
      <VxInput v-model="form.name" />
    </VxFormItem>
    <VxFormItem label="Email" field="email">
      <VxInput v-model="form.email" />
    </VxFormItem>
    <VxFormItem label="Password" field="password">
      <VxInput v-model="form.password" type="password" />
    </VxFormItem>
    <VxFormItem label="Confirm Password" field="confirmPassword">
      <VxInput v-model="form.confirmPassword" type="password" />
    </VxFormItem>
    <VxFormItem label="Phone" field="phone" help="Optional">
      <VxInput v-model="form.phone" />
    </VxFormItem>
    <VxFormItem label="Website" field="website" help="HTTPS required">
      <VxInput v-model="form.website" />
    </VxFormItem>
    <VxFormItem label="Role" field="role">
      <VxSelect v-model="form.role" :options="roles" />
    </VxFormItem>
    <VxFormItem label="Bio" field="bio" help="Max 200 characters">
      <VxInput v-model="form.bio" type="textarea" :rows="3" />
    </VxFormItem>
    <VxFormItem field="terms">
      <VxCheckbox v-model="form.terms" label="I accept the terms and conditions" />
    </VxFormItem>
    <VxFormItem>
      <VxButton @click="formRef.validate()">Register</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Nested Model ​

user.username kabi ichki obyekt xossalarini bog'lash va tekshirish uchun field da nuqtali yozuvdan foydalaning.

Optional, max 200 characters
vue
<script setup>
import { ref, reactive } from 'vue'

const formRef = ref()
const form = reactive({
  user: { username: '', password: '' },
  description: '',
})

// Use dot-notation keys to match nested field paths
const rules = {
  'user.username': [
    { required: true, message: 'Username is required' },
    { min: 3, max: 20, message: '3-20 characters' },
    { type: 'alphanumeric', message: 'Letters and numbers only' },
  ],
  'user.password': [
    { required: true, message: 'Password is required' },
    { min: 8, message: 'At least 8 characters' },
    { pattern: /[A-Z]/, message: 'Needs an uppercase letter' },
    { pattern: /[0-9]/, message: 'Needs a number' },
  ],
  description: [
    { max: 200, message: 'Max 200 characters' },
  ],
}

async function onSubmit() {
  const { valid } = await formRef.value.validate()
  if (valid) {
    console.log('Submitted:', JSON.parse(JSON.stringify(form)))
  }
}
</script>

<template>
  <VxForm ref="formRef" :model="form" :rules="rules">
    <VxFormItem label="Username" field="user.username">
      <VxInput v-model="form.user.username" placeholder="Letters and numbers, 3-20 chars" />
    </VxFormItem>
    <VxFormItem label="Password" field="user.password">
      <VxInput v-model="form.user.password" type="password" placeholder="8+ chars, uppercase, number" />
    </VxFormItem>
    <VxFormItem label="Description" field="description" help="Optional, max 200 characters">
      <VxInput v-model="form.description" type="textarea" :rows="3" />
    </VxFormItem>
    <VxFormItem>
      <VxButton @click="onSubmit">Submit</VxButton>
      <VxButton variant="outline" @click="formRef.resetFields()">Reset</VxButton>
    </VxFormItem>
  </VxForm>
</template>

Status Icons ​

Kiritish yonida tekshiruv holati ikonkalarini (spinner, belgi, xoch) ko'rsatish.

vue
<template>
  <VxForm ref="formRef" :model="form" :rules="rules" :status-icon="true">
    <VxFormItem label="Email" field="email">
      <VxInput v-model="form.email" />
    </VxFormItem>
  </VxForm>
</template>

Label Suffix ​

Barcha yorliqlarga suffiks belgisini (masalan, :) qo'shish.

vue
<template>
  <VxForm :model="form" label-suffix=":">
    <VxFormItem label="Name"><VxInput v-model="form.name" /></VxFormItem>
    <VxFormItem label="Age"><VxInput v-model="form.age" /></VxFormItem>
  </VxForm>
</template>

Scroll to Error ​

Tekshiruvdan so'ng xatolikka ega birinchi maydonga avtomatik aylantirish.

vue
<template>
  <VxForm ref="formRef" :model="form" :rules="rules" :scroll-to-error="true">
    <!-- fields -->
    <VxButton @click="formRef.validate()">Validate All</VxButton>
  </VxForm>
</template>

Show All Errors ​

Birinchi xatoda to'xtash o'rniga barcha qoida buzilishlarini bir vaqtning o'zida ko'rsatish.

vue
<template>
  <VxForm :model="form" :rules="rules" :show-all-errors="true">
    <VxFormItem label="Password" field="password">
      <VxInput v-model="form.password" />
    </VxFormItem>
  </VxForm>
</template>

<script setup>
const rules = {
  password: [
    { required: true, message: 'Password is required' },
    { min: 8, message: 'At least 8 characters' },
    { pattern: /[A-Z]/, message: 'Must contain an uppercase letter' },
    { pattern: /[0-9]/, message: 'Must contain a number' },
    { pattern: /[^a-zA-Z0-9]/, message: 'Must contain a special character' },
  ],
}
</script>

Loading State ​

Barcha o'zaro ta'sirlarni o'chirish va yuklash holatini ko'rsatish uchun loading ni o'rnating. disabled bilan birlashtiriladi.

vue
<script setup>
const loading = ref(false)
async function onSubmit() {
  loading.value = true
  await submitForm()
  loading.value = false
}
</script>

<template>
  <VxForm :model="form" :loading="loading">
    <!-- fields -->
    <VxButton @click="onSubmit">Submit</VxButton>
  </VxForm>
</template>

Dirty Tracking ​

Formaning o'zgartirilganligini kuzatish. isDirty va dirtyFields ga ref orqali kiring.

No changes
vue
<script setup>
const formRef = ref()
const form = reactive({ name: 'John', email: 'john@test.com' })
</script>

<template>
  <VxForm ref="formRef" :model="form">
    <!-- fields -->
    <VxButton :disabled="!formRef?.isDirty">Save Changes</VxButton>
    <span>{{ formRef?.isDirty ? `Modified: ${formRef?.dirtyFields}` : 'No changes' }}</span>
  </VxForm>
</template>

Dependent Field Re-validation ​

Boshqa maydon o'zgarganda qayta tekshirish uchun FormItem da dependencies prop dan foydalaning. "Parolni tasdiqlash" stsenariylari uchun foydali.

vue
<template>
  <VxForm :model="form" :rules="rules">
    <VxFormItem label="Password" field="password">
      <VxInput v-model="form.password" type="password" />
    </VxFormItem>
    <VxFormItem label="Confirm" field="confirm" :dependencies="['password']">
      <VxInput v-model="form.confirm" type="password" />
    </VxFormItem>
  </VxForm>
</template>

<script setup>
const rules = {
  password: [{ required: true }, { min: 6, message: 'At least 6 characters' }],
  confirm: [{ required: true }, { same: 'password', message: 'Passwords do not match' }],
}
</script>

Required Mark Position ​

Majburiy yulduzcha yorliqning chap yoki o'ng tomonida paydo bo'lishini boshqaring.

Left (default)
Right
vue
<template>
  <!-- Asterisk on left (default) -->
  <VxForm :model="form" :rules="rules" required-mark-position="left">...</VxForm>

  <!-- Asterisk on right -->
  <VxForm :model="form" :rules="rules" required-mark-position="right">...</VxForm>
</template>

Extra & Error Slots ​

Kiritish ostidagi maslahatlar uchun #extra dan, maxsus xatolik ko'rsatish uchun #error dan foydalaning.

Must be 8+ chars with uppercase, number, and special character.
vue
<template>
  <VxFormItem label="Password" field="password">
    <VxInput v-model="form.password" type="password" />
    <template #extra>
      <span>Must be 8+ chars with uppercase, number, and special character.</span>
    </template>
    <template #error="{ errors, first }">
      <ul>
        <li v-for="e in errors" :key="e">{{ e }}</li>
      </ul>
    </template>
  </VxFormItem>
</template>

Props ​

Form ​

PropTypeDefaultDescription
modelRecord<string, any>—Forma ma'lumotlari obyekti
rulesFormRules—Maydon nomi bo'yicha kalitlangan tekshiruv qoidalari
layout'vertical' | 'horizontal' | 'inline''vertical'Forma joylashuvi
labelWidthstring | number—Gorizontal joylashuv uchun yorliq kengligi
labelAlign'left' | 'right' | 'top''right'Gorizontal joylashuvda yorliq matnining tekislashi
labelSuffixstring''Barcha yorliqlarga qo'shilgan suffiks (masalan, :)
size'sm' | 'default' | 'lg''default'Forma o'lchami
disabledbooleanfalseButun formani o'chirish
loadingbooleanfalseYuklash holati — kursor hodisalarini o'chiradi
showRequiredMarkbooleantrueMajburiy maydonlarda qizil yulduzchani ko'rsatish
requiredMarkPosition'left' | 'right''left'Majburiy yulduzchaning joylashuvi
validateOnChangebooleantrueModel o'zgarganda avtomatik tekshirish
validateOnBlurbooleantrueMaydon fokusini yo'qotganda avtomatik tekshirish
hideErrorMessagebooleanfalseBarcha xatolik xabarlarini yashirish
scrollToErrorbooleanfalseTekshiruvdan so'ng birinchi xatolikka aylantirish
statusIconbooleanfalseKiritishlar yonida tekshiruv holati ikonkalarini ko'rsatish
showAllErrorsbooleanfalseFaqat birinchisi o'rniga barcha tekshiruv xatolarini ko'rsatish

FormItem ​

PropTypeDefaultDescription
labelstring''Yorliq matni
fieldstring''Maydon nomi (model va rules dagi kalitga mos kelishi kerak)
rulesFormRule | FormRule[]—Maydon darajasidagi qoidalar (forma darajasidagi bilan birlashtiriladi)
requiredboolean—Majburiy holatni bekor qilish (qoidalardan avtomatik aniqlanadi)
labelWidthstring | number—Forma darajasidagi yorliq kengligini bekor qilish
showMessagebooleantrueUshbu maydon uchun xatolik xabarini ko'rsatish
helpstring''Maydon ostidagi yordam matni
descriptionstring''Yorliq yonidagi ma'lumot ikonkasi orqali ko'rsatiladigan tooltip matni
dependenciesstring[]—Ro'yxatdagi maydonlar o'zgarganda ushbu maydonni qayta tekshirish

Events ​

EventPayloadDescription
validate(field, valid, message)Maydon tekshirilgandan so'ng ishga tushadi
submitEventTabiiy forma jo'natish (sukut bo'yicha oldini olinadi)

Exposed Methods ​

MethodSignatureDescription
validate() => Promise<{ valid, errors }>Barcha maydonlarni tekshirish
validateFields(fields: string[]) => Promise<{ valid, errors }>Muayyan maydonlarni tekshirish
resetFields() => voidTekshiruv holatini tiklash
clearValidation(fields?: string[]) => voidXatolik xabarlarini tozalash
isDirtyComputedRef<boolean>Biror maydon o'zgartirilganligi
dirtyFieldsComputedRef<string[]>O'zgartirilgan maydon nomlari ro'yxati
scrollToFirstError(field: string) => voidMuayyan maydonga aylantirish

Slots ​

FormItem ​

SlotPropsDescription
default—Forma boshqaruvi
label—Maxsus yorliq tarkibi
label-suffix—Yorliq matnidan keyingi tarkib
description—Boyitilgan tooltip tarkibi (description prop ni almashtiradi)
extra—Kiritish ostidagi qo'shimcha tarkib
error{ errors: string[], first: string }Maxsus xatolik xabarini ko'rsatish

FormRule ​

PropertyTypeDescription
requiredbooleanMaydon qiymatga ega bo'lishi kerak
messagestringMaxsus xatolik xabari
trigger'blur' | 'change' | ('blur' | 'change')[]Tekshiruvni qachon ishga tushirish
minnumberMinimal uzunlik/qiymat
maxnumberMaksimal uzunlik/qiymat
lennumberAniq uzunlik
patternRegExpMoslashtirish uchun Regex naqsh
typeFormRuleTypeO'rnatilgan tur validatori (quyiga qarang)
validator(value, rule) => boolean | string | PromiseMaxsus validator funksiyasi
whitespacebooleanFaqat bo'sh joylarni bo'sh deb hisoblash
enumany[]Qiymat shulardan biri bo'lishi kerak
notanyQiymat bunga teng bo'lmasligi kerak
samestringBoshqa maydon qiymatiga mos kelishi kerak
differentstringBoshqa maydon qiymatidan farq qilishi kerak
containsstringUshbu substringni o'z ichiga olishi kerak
startsWithstringUshbu satr bilan boshlanishi kerak
endsWithstringUshbu satr bilan tugashi kerak

Type Validators ​

TypeDescription
stringSatr bo'lishi kerak
numberRaqam bo'lishi kerak
integerButun son bo'lishi kerak
floatO'nlik son bo'lishi kerak
booleanBoolean bo'lishi kerak
arrayMassiv bo'lishi kerak
emailHaqiqiy email manzili
urlHaqiqiy URL
dateParslanishi mumkin bo'lgan sana satri
hexHaqiqiy hex rangi (#fff, #ff5733)
ipHaqiqiy IPv4 manzili
phoneHaqiqiy telefon raqami formati
alphaFaqat harflar (a-z, A-Z)
alphanumericFaqat harflar va raqamlar