Preview Updated 2026-05-10

Form

Form wrapper — unifies labels, required asterisks, hints, and error display, and integrates every existing input.

Basic usage

<CfForm> provides the layout context and <CfFormField> wraps each form item, rendering its label, required asterisk, and hint / error text uniformly. Validation is the consumer’s responsibility — the component simply displays error and turns the control’s border red.

用于登录

<CfForm layout="vertical">
<CfFormField label="Name">
  <CfInput v-model="name" placeholder="Jane Doe" />
</CfFormField>
<CfFormField label="Email" hint="Used for sign-in">
  <CfInput v-model="email" type="email" />
</CfFormField>
<CfButton>Submit</CfButton>
</CfForm>
<CfForm layout="vertical">
<CfFormField label="Name">
  <CfInput value={name} onChange={(e) => setName(e.target.value)} placeholder="Jane Doe" />
</CfFormField>
<CfFormField label="Email" hint="Used for sign-in">
  <CfInput value={email} onChange={(e) => setEmail(e.target.value)} type="email" />
</CfFormField>
<CfButton>Submit</CfButton>
</CfForm>

Three layouts

layout decides how the label and control are arranged:

  • vertical (default) — label above the control, the most common form layout
  • horizontal — label and control on the same row, paired with labelWidth for alignment
  • inline — fields packed onto a single row, useful for search bars and toolbars
layout = vertical(默认)
layout = horizontal
layout = inline
<CfForm layout="vertical">…</CfForm>
<CfForm layout="horizontal" :label-width="80">…</CfForm>
<CfForm layout="inline">…</CfForm>
<CfForm layout="vertical">…</CfForm>
<CfForm layout="horizontal" labelWidth={80}>…</CfForm>
<CfForm layout="inline">…</CfForm>

Validation and errors

required adds a red asterisk after the label. hint shows a hint below the control. When error is non-empty, the control border turns red and the error text replaces the hint. Validation logic (sync / async / third-party libraries) is fully owned by the parent — the component only displays error.

用于登录与接收通知

function submit() {
errors.value = {};
if (!name.value.trim()) errors.value.name = 'Name is required';
if (!email.value.includes('@')) errors.value.email = 'Invalid email';
}

<CfForm layout="vertical">
<CfFormField label="Name" required :error="errors.name">
  <CfInput v-model="name" />
</CfFormField>
<CfFormField label="Email" required hint="Used for sign-in" :error="errors.email">
  <CfInput v-model="email" type="email" />
</CfFormField>
<CfButton @click="submit">Submit</CfButton>
</CfForm>
function submit() {
const next: Record<string, string> = {};
if (!name.trim()) next.name = 'Name is required';
if (!email.includes('@')) next.email = 'Invalid email';
setErrors(next);
}

<CfForm layout="vertical">
<CfFormField label="Name" required error={errors.name}>
  <CfInput value={name} onChange={(e) => setName(e.target.value)} />
</CfFormField>
<CfFormField label="Email" required hint="Used for sign-in" error={errors.email}>
  <CfInput value={email} onChange={(e) => setEmail(e.target.value)} type="email" />
</CfFormField>
<CfButton onClick={submit}>Submit</CfButton>
</CfForm>

Complex form

A real-world form combining Input / Select / Textarea / Button.

用于登录与接收通知

<CfForm layout="vertical">
<CfFormField label="Name" required><CfInput v-model="name" /></CfFormField>
<CfFormField label="Email" required hint="Used for sign-in"><CfInput v-model="email" type="email" /></CfFormField>
<CfFormField label="Role"><CfSelect v-model="role" :options="roles" /></CfFormField>
<CfFormField label="Bio"><CfTextarea v-model="bio" :rows="3" /></CfFormField>
<CfButton>Submit</CfButton>
</CfForm>
<CfForm layout="vertical">
<CfFormField label="Name" required><CfInput ... /></CfFormField>
<CfFormField label="Email" required hint="Used for sign-in"><CfInput ... type="email" /></CfFormField>
<CfFormField label="Role"><CfSelect value={role} onChange={setRole} options={roles} /></CfFormField>
<CfFormField label="Bio"><CfTextarea value={bio} rows={3} ... /></CfFormField>
<CfButton>Submit</CfButton>
</CfForm>

API · Form props

PropTypeDefaultDescription
layout'vertical' | 'horizontal' | 'inline''vertical'Overall layout
size'sm' | 'md' | 'lg''md'Default size (visual placeholder for now; not yet wired to control sizes)
labelWidthnumber | stringHorizontal layout only; fixed label width
disabledbooleanfalseDisable globally (not yet wired to controls; pass through manually)

API · FormField props

PropTypeDescription
labelstring | ReactNodeLabel text
requiredbooleanShow required asterisk
hintstring | ReactNodeHint text below the control
errorstring | ReactNodeError text; turns the control border red when non-empty
for (Vue) / htmlFor (React)stringCustom input id; auto-generated if omitted
layoutFormLayoutOverride the parent Form layout for this field

反馈与讨论

Form · Discussion

0
0 / 600
一键发送
正在加载评论...