or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-components.mdbusiness-components.mddisplay-components.mdfeedback-components.mdform-components.mdindex.mdnavigation-components.mdutilities-composables.md

form-components.mddocs/

0

# Form Components

1

2

Comprehensive form controls for building interactive forms with validation, user input, and data selection. These components provide the foundation for mobile form interfaces.

3

4

## Capabilities

5

6

### Field

7

8

Primary text input component with extensive customization and validation support.

9

10

```typescript { .api }

11

import { Field } from 'vant';

12

13

interface FieldProps {

14

/** Input value */

15

modelValue?: string | number;

16

/** Input type */

17

type?: 'text' | 'number' | 'password' | 'textarea' | 'tel' | 'digit' | 'email' | 'url' | 'search';

18

/** Input name */

19

name?: string;

20

/** Field label */

21

label?: string;

22

/** Placeholder text */

23

placeholder?: string;

24

/** Left icon */

25

leftIcon?: string;

26

/** Right icon */

27

rightIcon?: string;

28

/** Disabled state */

29

disabled?: boolean;

30

/** Readonly state */

31

readonly?: boolean;

32

/** Required field marker */

33

required?: boolean;

34

/** Show clear button */

35

clearable?: boolean;

36

/** Clickable field */

37

clickable?: boolean;

38

/** Auto resize for textarea */

39

autosize?: boolean | { maxHeight?: number; minHeight?: number };

40

/** Maximum input length */

41

maxlength?: number | string;

42

/** Show word limit */

43

showWordLimit?: boolean;

44

/** Error message */

45

errorMessage?: string;

46

/** Formatter function */

47

formatter?: (value: string) => string;

48

/** Format trigger timing */

49

formatTrigger?: 'onChange' | 'onBlur';

50

/** Auto focus */

51

autofocus?: boolean;

52

/** Input align */

53

inputAlign?: 'left' | 'center' | 'right';

54

/** Label width */

55

labelWidth?: string | number;

56

/** Label align */

57

labelAlign?: 'left' | 'center' | 'right';

58

/** Label class */

59

labelClass?: string;

60

/** Input class */

61

inputClass?: string;

62

/** Size */

63

size?: 'large' | 'normal';

64

/** Border */

65

border?: boolean;

66

/** Center content */

67

center?: boolean;

68

/** Is link style */

69

isLink?: boolean;

70

/** Arrow direction */

71

arrowDirection?: 'left' | 'up' | 'down' | 'right';

72

}

73

74

// Events

75

interface FieldEvents {

76

'update:modelValue': (value: string) => void;

77

click: (event: MouseEvent) => void;

78

focus: (event: FocusEvent) => void;

79

blur: (event: FocusEvent) => void;

80

clear: (event: MouseEvent) => void;

81

'click-input': (event: MouseEvent) => void;

82

'click-left-icon': (event: MouseEvent) => void;

83

'click-right-icon': (event: MouseEvent) => void;

84

}

85

```

86

87

**Usage Example:**

88

89

```vue

90

<template>

91

<van-form @submit="onSubmit">

92

<van-cell-group inset>

93

<van-field

94

v-model="form.username"

95

name="username"

96

label="Username"

97

placeholder="Enter username"

98

:rules="[{ required: true, message: 'Username is required' }]"

99

/>

100

101

<van-field

102

v-model="form.password"

103

type="password"

104

name="password"

105

label="Password"

106

placeholder="Enter password"

107

:rules="[{ required: true, message: 'Password is required' }]"

108

/>

109

110

<van-field

111

v-model="form.phone"

112

type="tel"

113

name="phone"

114

label="Phone"

115

placeholder="Enter phone number"

116

maxlength="11"

117

show-word-limit

118

/>

119

</van-cell-group>

120

121

<div style="margin: 16px;">

122

<van-button round block type="primary" native-type="submit">

123

Submit

124

</van-button>

125

</div>

126

</van-form>

127

</template>

128

129

<script setup lang="ts">

130

import { reactive } from 'vue';

131

import { Field, Form, CellGroup, Button } from 'vant';

132

133

const form = reactive({

134

username: '',

135

password: '',

136

phone: ''

137

});

138

139

const onSubmit = (values: any) => {

140

console.log('Form submitted:', values);

141

};

142

</script>

143

```

144

145

### Form

146

147

Form container component with validation and submission handling.

148

149

```typescript { .api }

150

import { Form } from 'vant';

151

152

interface FormProps {

153

/** Colon after label */

154

colon?: boolean;

155

/** Disabled state */

156

disabled?: boolean;

157

/** Readonly state */

158

readonly?: boolean;

159

/** Show error */

160

showError?: boolean;

161

/** Show error message */

162

showErrorMessage?: boolean;

163

/** Submit on enter */

164

submitOnEnter?: boolean;

165

/** Validate first error only */

166

validateFirst?: boolean;

167

/** Validate trigger */

168

validateTrigger?: 'onBlur' | 'onChange' | 'onSubmit';

169

/** Scroll to error */

170

scrollToError?: boolean;

171

}

172

173

interface FormInstance {

174

submit: () => void;

175

validate: (name?: string) => Promise<any>;

176

resetValidation: (name?: string) => void;

177

getValidationStatus: () => boolean;

178

scrollToField: (name: string) => void;

179

}

180

```

181

182

### Checkbox

183

184

Checkbox component for multiple selections with group support.

185

186

```typescript { .api }

187

import { Checkbox, CheckboxGroup } from 'vant';

188

189

interface CheckboxProps {

190

/** Checked state */

191

modelValue?: boolean;

192

/** Checkbox name */

193

name?: string | number;

194

/** Checkbox shape */

195

shape?: 'square' | 'round';

196

/** Disabled state */

197

disabled?: boolean;

198

/** Label disabled */

199

labelDisabled?: boolean;

200

/** Label position */

201

labelPosition?: 'left' | 'right';

202

/** Icon size */

203

iconSize?: string | number;

204

/** Checked color */

205

checkedColor?: string;

206

/** Bind object value in group */

207

bindGroup?: boolean;

208

/** Indeterminate state */

209

indeterminate?: boolean;

210

}

211

212

interface CheckboxGroupProps {

213

/** Selected values */

214

modelValue?: any[];

215

/** Disabled state */

216

disabled?: boolean;

217

/** Maximum selections */

218

max?: number | string;

219

/** Direction */

220

direction?: 'horizontal' | 'vertical';

221

/** Icon size */

222

iconSize?: string | number;

223

/** Checked color */

224

checkedColor?: string;

225

}

226

```

227

228

### Radio

229

230

Radio button component for single selections.

231

232

```typescript { .api }

233

import { Radio, RadioGroup } from 'vant';

234

235

interface RadioProps {

236

/** Radio value */

237

name?: any;

238

/** Checked state */

239

modelValue?: any;

240

/** Disabled state */

241

disabled?: boolean;

242

/** Label disabled */

243

labelDisabled?: boolean;

244

/** Label position */

245

labelPosition?: 'left' | 'right';

246

/** Icon size */

247

iconSize?: string | number;

248

/** Checked color */

249

checkedColor?: string;

250

/** Radio shape */

251

shape?: 'square' | 'round';

252

}

253

254

interface RadioGroupProps {

255

/** Selected value */

256

modelValue?: any;

257

/** Disabled state */

258

disabled?: boolean;

259

/** Direction */

260

direction?: 'horizontal' | 'vertical';

261

/** Icon size */

262

iconSize?: string | number;

263

/** Checked color */

264

checkedColor?: string;

265

}

266

```

267

268

### Switch

269

270

Toggle switch component for binary states.

271

272

```typescript { .api }

273

import { Switch } from 'vant';

274

275

interface SwitchProps {

276

/** Switch state */

277

modelValue?: boolean;

278

/** Loading state */

279

loading?: boolean;

280

/** Disabled state */

281

disabled?: boolean;

282

/** Switch size */

283

size?: string | number;

284

/** Active color */

285

activeColor?: string;

286

/** Inactive color */

287

inactiveColor?: string;

288

/** Active value */

289

activeValue?: any;

290

/** Inactive value */

291

inactiveValue?: any;

292

}

293

```

294

295

### Stepper

296

297

Numeric stepper component for incrementing/decrementing values.

298

299

```typescript { .api }

300

import { Stepper } from 'vant';

301

302

interface StepperProps {

303

/** Current value */

304

modelValue?: number | string;

305

/** Minimum value */

306

min?: number | string;

307

/** Maximum value */

308

max?: number | string;

309

/** Default value */

310

defaultValue?: number | string;

311

/** Step size */

312

step?: number | string;

313

/** Input name */

314

name?: string;

315

/** Integer only */

316

integer?: boolean;

317

/** Disabled state */

318

disabled?: boolean;

319

/** Disable plus button */

320

disablePlus?: boolean;

321

/** Disable minus button */

322

disableMinus?: boolean;

323

/** Disable input */

324

disableInput?: boolean;

325

/** Readonly input */

326

readonly?: boolean;

327

/** Input width */

328

inputWidth?: string | number;

329

/** Button size */

330

buttonSize?: string | number;

331

/** Show plus button */

332

showPlus?: boolean;

333

/** Show minus button */

334

showMinus?: boolean;

335

/** Show input */

336

showInput?: boolean;

337

/** Long press */

338

longPress?: boolean;

339

/** Allow empty */

340

allowEmpty?: boolean;

341

/** Placeholder */

342

placeholder?: string;

343

}

344

```

345

346

### Picker

347

348

Multi-column picker component for selecting values from predefined options.

349

350

```typescript { .api }

351

import { Picker } from 'vant';

352

353

interface PickerProps {

354

/** Picker columns */

355

columns?: PickerColumn[] | PickerColumn[][];

356

/** Default selected indexes */

357

defaultIndex?: number | number[];

358

/** Toolbar position */

359

toolbarPosition?: 'top' | 'bottom';

360

/** Show toolbar */

361

showToolbar?: boolean;

362

/** Title */

363

title?: string;

364

/** Confirm button text */

365

confirmButtonText?: string;

366

/** Cancel button text */

367

cancelButtonText?: string;

368

/** Loading state */

369

loading?: boolean;

370

/** Readonly state */

371

readonly?: boolean;

372

/** Item height */

373

itemHeight?: number | string;

374

/** Visible item count */

375

visibleItemCount?: number | string;

376

/** Swipe duration */

377

swipeDuration?: number | string;

378

}

379

380

interface PickerColumn {

381

text?: string;

382

value?: string | number;

383

disabled?: boolean;

384

children?: PickerColumn[];

385

className?: string;

386

}

387

388

interface PickerInstance {

389

confirm: () => void;

390

getSelectedOptions: () => PickerColumn[];

391

setColumnValues: (columnIndex: number, values: PickerColumn[]) => void;

392

setColumnValue: (columnIndex: number, value: string | number) => void;

393

setColumnIndex: (columnIndex: number, optionIndex: number) => void;

394

getColumnValue: (columnIndex: number) => string | number;

395

getColumnIndex: (columnIndex: number) => number;

396

getValues: () => (string | number)[];

397

setValues: (values: (string | number)[]) => void;

398

getIndexes: () => number[];

399

setIndexes: (indexes: number[]) => void;

400

}

401

```

402

403

### DatePicker

404

405

Date selection component with various modes and customization options.

406

407

```typescript { .api }

408

import { DatePicker } from 'vant';

409

410

interface DatePickerProps {

411

/** Selected date */

412

modelValue?: Date;

413

/** Picker type */

414

type?: 'date' | 'time' | 'datetime' | 'datehour' | 'month-day' | 'year-month';

415

/** Title */

416

title?: string;

417

/** Confirm button text */

418

confirmButtonText?: string;

419

/** Cancel button text */

420

cancelButtonText?: string;

421

/** Show toolbar */

422

showToolbar?: boolean;

423

/** Loading state */

424

loading?: boolean;

425

/** Readonly state */

426

readonly?: boolean;

427

/** Filter options */

428

filter?: (type: string, values: string[]) => string[];

429

/** Formatter */

430

formatter?: (type: string, value: string) => string;

431

/** Columns order */

432

columnsOrder?: string[];

433

/** Min date */

434

minDate?: Date;

435

/** Max date */

436

maxDate?: Date;

437

}

438

```

439

440

### TimePicker

441

442

Time selection component for hour, minute, and second selection.

443

444

```typescript { .api }

445

import { TimePicker } from 'vant';

446

447

interface TimePickerProps {

448

/** Selected time */

449

modelValue?: string;

450

/** Title */

451

title?: string;

452

/** Confirm button text */

453

confirmButtonText?: string;

454

/** Cancel button text */

455

cancelButtonText?: string;

456

/** Show toolbar */

457

showToolbar?: boolean;

458

/** Loading state */

459

loading?: boolean;

460

/** Readonly state */

461

readonly?: boolean;

462

/** Filter options */

463

filter?: (type: string, values: string[]) => string[];

464

/** Formatter */

465

formatter?: (type: string, value: string) => string;

466

/** Columns order */

467

columnsOrder?: string[];

468

/** Min hour */

469

minHour?: number | string;

470

/** Max hour */

471

maxHour?: number | string;

472

/** Min minute */

473

minMinute?: number | string;

474

/** Max minute */

475

maxMinute?: number | string;

476

/** Min second */

477

minSecond?: number | string;

478

/** Max second */

479

maxSecond?: number | string;

480

}

481

```

482

483

### Calendar

484

485

Calendar component for date range selection with various display modes.

486

487

```typescript { .api }

488

import { Calendar } from 'vant';

489

490

interface CalendarProps {

491

/** Calendar type */

492

type?: 'single' | 'multiple' | 'range';

493

/** Selected date(s) */

494

modelValue?: Date | Date[] | null;

495

/** Show calendar */

496

show?: boolean;

497

/** Title */

498

title?: string;

499

/** Subtitle */

500

subtitle?: string;

501

/** Color */

502

color?: string;

503

/** Min date */

504

minDate?: Date;

505

/** Max date */

506

minDate?: Date;

507

/** Default date */

508

defaultDate?: Date | Date[] | null;

509

/** Row height */

510

rowHeight?: number | string;

511

/** Formatter */

512

formatter?: (day: CalendarDay) => CalendarDay;

513

/** Poppable */

514

poppable?: boolean;

515

/** Lazy render */

516

lazyRender?: boolean;

517

/** Show mark */

518

showMark?: boolean;

519

/** Show title */

520

showTitle?: boolean;

521

/** Show subtitle */

522

showSubtitle?: boolean;

523

/** Show confirm */

524

showConfirm?: boolean;

525

/** Readonly */

526

readonly?: boolean;

527

/** Confirm text */

528

confirmText?: string;

529

/** Confirm disabled text */

530

confirmDisabledText?: string;

531

/** First day of week */

532

firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;

533

}

534

535

interface CalendarDay {

536

date?: Date;

537

type?: string;

538

text?: string | number;

539

topInfo?: string;

540

bottomInfo?: string;

541

disabled?: boolean;

542

className?: string;

543

}

544

```

545

546

### Rate

547

548

Star rating component for user feedback and ratings.

549

550

```typescript { .api }

551

import { Rate } from 'vant';

552

553

interface RateProps {

554

/** Current rate */

555

modelValue?: number;

556

/** Star count */

557

count?: number | string;

558

/** Star size */

559

size?: number | string;

560

/** Gutter between stars */

561

gutter?: number | string;

562

/** Star color */

563

color?: string;

564

/** Void star color */

565

voidColor?: string;

566

/** Disabled star color */

567

disabledColor?: string;

568

/** Star icon */

569

icon?: string;

570

/** Void star icon */

571

voidIcon?: string;

572

/** Icon prefix */

573

iconPrefix?: string;

574

/** Allow half star */

575

allowHalf?: boolean;

576

/** Readonly state */

577

readonly?: boolean;

578

/** Disabled state */

579

disabled?: boolean;

580

/** Touchable */

581

touchable?: boolean;

582

}

583

```

584

585

### Uploader

586

587

File upload component with preview and progress tracking.

588

589

```typescript { .api }

590

import { Uploader } from 'vant';

591

592

interface UploaderProps {

593

/** File list */

594

modelValue?: UploaderFileListItem[];

595

/** Accept file types */

596

accept?: string;

597

/** Maximum file count */

598

maxCount?: number | string;

599

/** Maximum file size */

600

maxSize?: number | string;

601

/** Preview size */

602

previewSize?: number | string;

603

/** Preview image */

604

previewImage?: boolean;

605

/** Preview full image */

606

previewFullImage?: boolean;

607

/** Multiple selection */

608

multiple?: boolean;

609

/** Disabled state */

610

disabled?: boolean;

611

/** Readonly state */

612

readonly?: boolean;

613

/** Deletable */

614

deletable?: boolean;

615

/** Show upload */

616

showUpload?: boolean;

617

/** Capture */

618

capture?: string;

619

/** After read */

620

afterRead?: (file: UploaderFileListItem | UploaderFileListItem[]) => void;

621

/** Before read */

622

beforeRead?: (file: File | File[]) => boolean | Promise<File | File[]>;

623

/** Before delete */

624

beforeDelete?: (file: UploaderFileListItem, detail: { name: string; index: number }) => boolean | Promise<boolean>;

625

/** Upload area text */

626

uploadText?: string;

627

/** Upload icon */

628

uploadIcon?: string;

629

/** Image fit */

630

imageFit?: string;

631

/** Result type */

632

resultType?: 'file' | 'text' | 'dataUrl';

633

}

634

635

interface UploaderFileListItem {

636

url?: string;

637

file?: File;

638

content?: string;

639

status?: 'uploading' | 'success' | 'failed';

640

message?: string;

641

name?: string;

642

isImage?: boolean;

643

deletable?: boolean;

644

previewSize?: number | string;

645

imageFit?: string;

646

}

647

```

648

649

### Form

650

651

Form container component providing validation and field management.

652

653

```typescript { .api }

654

import { Form } from 'vant';

655

656

interface FormProps {

657

/** Colon after label */

658

colon?: boolean;

659

/** Disabled state */

660

disabled?: boolean;

661

/** Label width */

662

labelWidth?: string | number;

663

/** Label align */

664

labelAlign?: 'left' | 'center' | 'right';

665

/** Input align */

666

inputAlign?: 'left' | 'center' | 'right';

667

/** Scroll to error field */

668

scrollToError?: boolean;

669

/** Validate first error only */

670

validateFirst?: boolean;

671

/** Submit on enter */

672

submitOnEnter?: boolean;

673

/** Show error */

674

showError?: boolean;

675

/** Show error message */

676

showErrorMessage?: boolean;

677

/** Validate trigger */

678

validateTrigger?: 'onBlur' | 'onChange' | 'onSubmit';

679

}

680

681

// Events

682

interface FormEvents {

683

/** Triggered when form is submitted */

684

submit: (values: Record<string, any>) => void;

685

/** Triggered when form validation fails */

686

failed: (errorInfo: FormErrorInfo) => void;

687

}

688

689

// Instance methods

690

interface FormInstance {

691

/** Submit form */

692

submit: () => void;

693

/** Validate all fields */

694

validate: (name?: string | string[]) => Promise<void>;

695

/** Reset all fields to initial values */

696

resetValidation: (name?: string | string[]) => void;

697

/** Get field values */

698

getValues: () => Record<string, any>;

699

/** Scroll to field */

700

scrollToField: (name: string, options?: ScrollIntoViewOptions) => void;

701

}

702

703

interface FormErrorInfo {

704

name: string;

705

message: string;

706

}

707

```

708

709

**Usage Example:**

710

711

```vue

712

<template>

713

<van-form @submit="onSubmit" @failed="onFailed">

714

<van-field

715

v-model="username"

716

name="username"

717

label="Username"

718

placeholder="Username"

719

:rules="[{ required: true, message: 'Please fill in username' }]"

720

/>

721

<van-field

722

v-model="password"

723

type="password"

724

name="password"

725

label="Password"

726

placeholder="Password"

727

:rules="[{ required: true, message: 'Please fill in password' }]"

728

/>

729

<div style="margin: 16px;">

730

<van-button round block type="primary" native-type="submit">

731

Submit

732

</van-button>

733

</div>

734

</van-form>

735

</template>

736

737

<script setup lang="ts">

738

import { ref } from 'vue';

739

import { Form, Field, Button } from 'vant';

740

741

const username = ref('');

742

const password = ref('');

743

744

const onSubmit = (values: any) => {

745

console.log('submit', values);

746

};

747

748

const onFailed = (errorInfo: any) => {

749

console.log('failed', errorInfo);

750

};

751

</script>

752

```

753

754

### Cascader

755

756

Cascading selection component for hierarchical data selection.

757

758

```typescript { .api }

759

import { Cascader } from 'vant';

760

761

interface CascaderProps {

762

/** Options data */

763

options: CascaderOption[];

764

/** Selected value */

765

modelValue?: string | number;

766

/** Field names mapping */

767

fieldNames?: CascaderFieldNames;

768

/** Placeholder */

769

placeholder?: string;

770

/** Active color */

771

activeColor?: string;

772

/** Show header */

773

showHeader?: boolean;

774

/** Title */

775

title?: string;

776

/** Close icon */

777

closeIcon?: string;

778

/** Swipeable tabs */

779

swipeable?: boolean;

780

/** Closeable */

781

closeable?: boolean;

782

}

783

784

interface CascaderOption {

785

text: string;

786

value: string | number;

787

color?: string;

788

disabled?: boolean;

789

children?: CascaderOption[];

790

}

791

792

interface CascaderFieldNames {

793

text?: string;

794

value?: string;

795

children?: string;

796

}

797

798

// Events

799

interface CascaderEvents {

800

/** Triggered when selection changes */

801

change: (value: string | number, selectedOptions: CascaderOption[], selectedItems: CascaderOption[]) => void;

802

/** Triggered when cascade item is clicked */

803

clickTab: (tabIndex: number, title: string) => void;

804

/** Triggered when close button is clicked */

805

close: () => void;

806

/** Triggered when selection is finished */

807

finish: (selectedOptions: CascaderOption[]) => void;

808

}

809

```

810

811

**Usage Example:**

812

813

```vue

814

<template>

815

<van-cascader

816

v-model="cascaderValue"

817

title="Select Area"

818

:options="options"

819

@change="onChange"

820

@finish="onFinish"

821

/>

822

</template>

823

824

<script setup lang="ts">

825

import { ref } from 'vue';

826

import { Cascader } from 'vant';

827

828

const cascaderValue = ref('');

829

const options = [

830

{

831

text: 'Zhejiang',

832

value: '330000',

833

children: [

834

{

835

text: 'Hangzhou',

836

value: '330100',

837

children: [

838

{ text: 'Xihu District', value: '330106' },

839

{ text: 'Yuhang District', value: '330110' },

840

],

841

},

842

],

843

},

844

];

845

846

const onChange = (value: any, selectedOptions: any) => {

847

console.log('change', value, selectedOptions);

848

};

849

850

const onFinish = (selectedOptions: any) => {

851

console.log('finish', selectedOptions);

852

};

853

</script>

854

```

855

856

### Signature

857

858

Signature pad component for capturing handwritten signatures.

859

860

```typescript { .api }

861

import { Signature } from 'vant';

862

863

interface SignatureProps {

864

/** Pen color */

865

penColor?: string;

866

/** Line width */

867

lineWidth?: number;

868

/** Background color */

869

backgroundColor?: string;

870

/** Clear button text */

871

clearButtonText?: string;

872

/** Confirm button text */

873

confirmButtonText?: string;

874

}

875

876

// Events

877

interface SignatureEvents {

878

/** Triggered when signature is submitted */

879

submit: (data: { image: string; canvas: HTMLCanvasElement }) => void;

880

/** Triggered when signature is cleared */

881

clear: () => void;

882

/** Triggered when signature starts */

883

start: () => void;

884

/** Triggered when signature ends */

885

end: () => void;

886

/** Triggered when signing */

887

signing: (event: TouchEvent) => void;

888

}

889

890

// Instance methods

891

interface SignatureInstance {

892

/** Resize signature pad */

893

resize: () => void;

894

/** Clear signature */

895

clear: () => void;

896

/** Get signature data */

897

submit: () => void;

898

}

899

```

900

901

**Usage Example:**

902

903

```vue

904

<template>

905

<div>

906

<van-signature

907

@submit="onSubmit"

908

@clear="onClear"

909

:line-width="3"

910

pen-color="#000"

911

/>

912

</div>

913

</template>

914

915

<script setup lang="ts">

916

import { Signature } from 'vant';

917

918

const onSubmit = (data: any) => {

919

console.log('Signature submitted:', data.image);

920

};

921

922

const onClear = () => {

923

console.log('Signature cleared');

924

};

925

</script>

926

```