<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
</script>
<template>
<div class="w-full max-w-md">
<form>
<FieldGroup>
<FieldSet>
<FieldLegend>Payment Method</FieldLegend>
<FieldDescription>
All transactions are secure and encrypted
</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="checkout-7j9-card-name-43j">
Name on Card
</FieldLabel>
<Input
id="checkout-7j9-card-name-43j"
placeholder="Evil Rabbit"
required
/>
</Field>
<Field>
<FieldLabel for="checkout-7j9-card-number-uw1">
Card Number
</FieldLabel>
<Input
id="checkout-7j9-card-number-uw1"
placeholder="1234 5678 9012 3456"
required
/>
<FieldDescription>
Enter your 16-digit card number
</FieldDescription>
</Field>
<div class="grid grid-cols-3 gap-4">
<Field>
<FieldLabel for="checkout-exp-month-ts6">
Month
</FieldLabel>
<Select default-value="">
<SelectTrigger id="checkout-exp-month-ts6">
<SelectValue placeholder="MM" />
</SelectTrigger>
<SelectContent>
<SelectItem value="01">
01
</SelectItem>
<SelectItem value="02">
02
</SelectItem>
<SelectItem value="03">
03
</SelectItem>
<SelectItem value="04">
04
</SelectItem>
<SelectItem value="05">
05
</SelectItem>
<SelectItem value="06">
06
</SelectItem>
<SelectItem value="07">
07
</SelectItem>
<SelectItem value="08">
08
</SelectItem>
<SelectItem value="09">
09
</SelectItem>
<SelectItem value="10">
10
</SelectItem>
<SelectItem value="11">
11
</SelectItem>
<SelectItem value="12">
12
</SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel for="checkout-7j9-exp-year-f59">
Year
</FieldLabel>
<Select default-value="">
<SelectTrigger id="checkout-7j9-exp-year-f59">
<SelectValue placeholder="YYYY" />
</SelectTrigger>
<SelectContent>
<SelectItem value="2024">
2024
</SelectItem>
<SelectItem value="2025">
2025
</SelectItem>
<SelectItem value="2026">
2026
</SelectItem>
<SelectItem value="2027">
2027
</SelectItem>
<SelectItem value="2028">
2028
</SelectItem>
<SelectItem value="2029">
2029
</SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel for="checkout-7j9-cvv">
CVV
</FieldLabel>
<Input id="checkout-7j9-cvv" placeholder="123" required />
</Field>
</div>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldLegend>Billing Address</FieldLegend>
<FieldDescription>
The billing address associated with your payment method
</FieldDescription>
<FieldGroup>
<Field orientation="horizontal">
<Checkbox
id="checkout-7j9-same-as-shipping-wgm"
:default-value="true"
/>
<FieldLabel
for="checkout-7j9-same-as-shipping-wgm"
class="font-normal"
>
Same as shipping address
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
<FieldSet>
<FieldGroup>
<Field>
<FieldLabel for="checkout-7j9-optional-comments">
Comments
</FieldLabel>
<Textarea
id="checkout-7j9-optional-comments"
placeholder="Add any additional comments"
class="resize-none"
/>
</Field>
</FieldGroup>
</FieldSet>
<Field orientation="horizontal">
<Button type="submit">
Submit
</Button>
<Button variant="outline" type="button">
Cancel
</Button>
</Field>
</FieldGroup>
</form>
</div>
</template>安装
🌐 Installation
pnpm dlx shadcn-vue@latest add field
用法
🌐 Usage
<script setup lang="ts">
import {
Field,
FieldContent,
FieldDescription,
FieldError,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
FieldTitle,
} from '@/components/ui/field'
</script>
<template>
<FieldSet>
<FieldLegend>Profile</FieldLegend>
<FieldDescription>This appears on invoices and emails.</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="name">
Full name
</FieldLabel>
<Input id="name" autocomplete="off" placeholder="Evil Rabbit" />
<FieldDescription>This appears on invoices and emails.</FieldDescription>
</Field>
<Field>
<FieldLabel for="username">
Username
</FieldLabel>
<Input id="username" autocomplete="off" aria-invalid />
<FieldError>Choose another username.</FieldError>
</Field>
<Field orientation="horizontal">
<Switch id="newsletter" />
<FieldLabel for="newsletter">
Subscribe to the newsletter
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
</template>剖析
🌐 Anatomy
Field 系列旨在用于创建可访问的表单。一个典型的字段结构如下:
🌐 The Field family is designed for composing accessible forms. A typical field is structured as follows:
<template>
<Field>
<FieldLabel for="input-id">
Label
</FieldLabel>
<!-- Input, Select, Switch, etc. -->
<FieldDescription>Optional helper text.</FieldDescription>
<FieldError>Validation message.</FieldError>
</Field>
</template>Field是单个字段的核心封装器。FieldContent是一个弹性列,用于组合标签和描述。如果没有描述,则不是必需的。- 用
FieldGroup封装相关字段,并使用FieldSet和FieldLegend进行语义分组。
示例
🌐 Examples
输入
🌐 Input
<script setup lang="ts">
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
</script>
<template>
<div class="w-full max-w-md">
<FieldSet>
<FieldGroup>
<Field>
<FieldLabel for="username">
Username
</FieldLabel>
<Input id="username" type="text" placeholder="Max Leiter" />
<FieldDescription>
Choose a unique username for your account.
</FieldDescription>
</Field>
<Field>
<FieldLabel for="password">
Password
</FieldLabel>
<FieldDescription>
Must be at least 8 characters long.
</FieldDescription>
<Input id="password" type="password" placeholder="********" />
</Field>
</FieldGroup>
</FieldSet>
</div>
</template>文本区域
🌐 Textarea
<script setup lang="ts">
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSet,
} from '@/components/ui/field'
import { Textarea } from '@/components/ui/textarea'
</script>
<template>
<div class="w-full max-w-md">
<FieldSet>
<FieldGroup>
<Field>
<FieldLabel for="feedback">
Feedback
</FieldLabel>
<Textarea
id="feedback"
placeholder="Your feedback helps us improve..."
:rows="4"
/>
<FieldDescription>
Share your thoughts about our service.
</FieldDescription>
</Field>
</FieldGroup>
</FieldSet>
</div>
</template>选择
🌐 Select
Select your department or area of work.
<script setup lang="ts">
import {
Field,
FieldDescription,
FieldLabel,
} from '@/components/ui/field'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
</script>
<template>
<div class="w-full max-w-md">
<Field>
<FieldLabel>Department</FieldLabel>
<Select>
<SelectTrigger>
<SelectValue placeholder="Choose department" />
</SelectTrigger>
<SelectContent>
<SelectItem value="engineering">
Engineering
</SelectItem>
<SelectItem value="design">
Design
</SelectItem>
<SelectItem value="marketing">
Marketing
</SelectItem>
<SelectItem value="sales">
Sales
</SelectItem>
<SelectItem value="support">
Customer Support
</SelectItem>
<SelectItem value="hr">
Human Resources
</SelectItem>
<SelectItem value="finance">
Finance
</SelectItem>
<SelectItem value="operations">
Operations
</SelectItem>
</SelectContent>
</Select>
<FieldDescription>
Select your department or area of work.
</FieldDescription>
</Field>
</div>
</template>滑块
🌐 Slider
Set your budget range ($ 200 - 800).
<script setup lang="ts">
import { ref } from 'vue'
import {
Field,
FieldDescription,
FieldTitle,
} from '@/components/ui/field'
import { Slider } from '@/components/ui/slider'
const value = ref([200, 800])
</script>
<template>
<div class="w-full max-w-md">
<Field>
<FieldTitle>Price Range</FieldTitle>
<FieldDescription>
Set your budget range ($
<span class="font-medium tabular-nums">{{ value[0] }}</span> -
<span class="font-medium tabular-nums">{{ value[1] }}</span>).
</FieldDescription>
<Slider
v-model="value"
:max="1000"
:min="0"
:step="10"
class="mt-2 w-full"
aria-label="Price Range"
/>
</Field>
</div>
</template>字段集
🌐 Fieldset
<script setup lang="ts">
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
</script>
<template>
<div class="w-full max-w-md space-y-6">
<FieldSet>
<FieldLegend>Address Information</FieldLegend>
<FieldDescription>
We need your address to deliver your order.
</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="street">
Street Address
</FieldLabel>
<Input id="street" type="text" placeholder="123 Main St" />
</Field>
<div class="grid grid-cols-2 gap-4">
<Field>
<FieldLabel for="city">
City
</FieldLabel>
<Input id="city" type="text" placeholder="New York" />
</Field>
<Field>
<FieldLabel for="zip">
Postal Code
</FieldLabel>
<Input id="zip" type="text" placeholder="90502" />
</Field>
</div>
</FieldGroup>
</FieldSet>
</div>
</template>复选框
🌐 Checkbox
Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.
<script setup lang="ts">
import { Checkbox } from '@/components/ui/checkbox'
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
} from '@/components/ui/field'
</script>
<template>
<div class="w-full max-w-md">
<FieldGroup>
<FieldSet>
<FieldLegend variant="label">
Show these items on the desktop
</FieldLegend>
<FieldDescription>
Select the items you want to show on the desktop.
</FieldDescription>
<FieldGroup class="gap-3">
<Field orientation="horizontal">
<Checkbox id="finder-pref-9k2-hard-disks-ljj" />
<FieldLabel
for="finder-pref-9k2-hard-disks-ljj"
class="font-normal"
:default-value="true"
>
Hard disks
</FieldLabel>
</Field>
<Field orientation="horizontal">
<Checkbox id="finder-pref-9k2-external-disks-1yg" />
<FieldLabel
for="finder-pref-9k2-external-disks-1yg"
class="font-normal"
>
External disks
</FieldLabel>
</Field>
<Field orientation="horizontal">
<Checkbox id="finder-pref-9k2-cds-dvds-fzt" />
<FieldLabel
for="finder-pref-9k2-cds-dvds-fzt"
class="font-normal"
>
CDs, DVDs, and iPods
</FieldLabel>
</Field>
<Field orientation="horizontal">
<Checkbox id="finder-pref-9k2-connected-servers-6l2" />
<FieldLabel
for="finder-pref-9k2-connected-servers-6l2"
class="font-normal"
>
Connected servers
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<Field orientation="horizontal">
<Checkbox id="finder-pref-9k2-sync-folders-nep" :default-value="true" />
<FieldContent>
<FieldLabel for="finder-pref-9k2-sync-folders-nep">
Sync Desktop & Documents folders
</FieldLabel>
<FieldDescription>
Your Desktop & Documents folders are being synced with iCloud
Drive. You can access them from other devices.
</FieldDescription>
</FieldContent>
</Field>
</FieldGroup>
</div>
</template>单选框
🌐 Radio
<script setup lang="ts">
import {
Field,
FieldDescription,
FieldLabel,
FieldSet,
} from '@/components/ui/field'
import {
RadioGroup,
RadioGroupItem,
} from '@/components/ui/radio-group'
</script>
<template>
<div class="w-full max-w-md">
<FieldSet>
<FieldLabel>Subscription Plan</FieldLabel>
<FieldDescription>
Yearly and lifetime plans offer significant savings.
</FieldDescription>
<RadioGroup defaultvalue="monthly">
<Field orientation="horizontal">
<RadioGroupItem id="plan-monthly" value="monthly" />
<FieldLabel for="plan-monthly" class="font-normal">
Monthly ($9.99/month)
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem id="plan-yearly" value="yearly" />
<FieldLabel for="plan-yearly" class="font-normal">
Yearly ($99.99/year)
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem id="plan-lifetime" value="lifetime" />
<FieldLabel for="plan-lifetime" class="font-normal">
Lifetime ($299.99)
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
</div>
</template>切换
🌐 Switch
Enable multi-factor authentication. If you do not have a two-factor device, you can use a one-time code sent to your email.
<script setup lang="ts">
import {
Field,
FieldContent,
FieldDescription,
FieldLabel,
} from '@/components/ui/field'
import { Switch } from '@/components/ui/switch'
</script>
<template>
<div class="w-full max-w-md">
<Field orientation="horizontal">
<FieldContent>
<FieldLabel for="2fa">
Multi-factor authentication
</FieldLabel>
<FieldDescription>
Enable multi-factor authentication. If you do not have a two-factor
device, you can use a one-time code sent to your email.
</FieldDescription>
</FieldContent>
<Switch id="2fa" />
</Field>
</div>
</template>选择卡
🌐 Choice Card
将 Field 组件封装在 FieldLabel 内以创建可选择的字段组。这适用于 RadioItem、Checkbox 和 Switch 组件。
🌐 Wrap Field components inside FieldLabel to create selectable field groups. This works with RadioItem, Checkbox and Switch components.
<script setup lang="ts">
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSet,
FieldTitle,
} from '@/components/ui/field'
import {
RadioGroup,
RadioGroupItem,
} from '@/components/ui/radio-group'
</script>
<template>
<div class="w-full max-w-md">
<FieldGroup>
<FieldSet>
<FieldLabel for="compute-environment-p8w">
Compute Environment
</FieldLabel>
<FieldDescription>
Select the compute environment for your cluster.
</FieldDescription>
<RadioGroup default-value="kubernetes">
<FieldLabel for="kubernetes-r2h">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Kubernetes</FieldTitle>
<FieldDescription>
Run GPU workloads on a K8s configured cluster.
</FieldDescription>
</FieldContent>
<RadioGroupItem id="kubernetes-r2h" value="kubernetes" />
</Field>
</FieldLabel>
<FieldLabel for="vm-z4k">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Virtual Machine</FieldTitle>
<FieldDescription>
Access a VM configured cluster to run GPU workloads.
</FieldDescription>
</FieldContent>
<RadioGroupItem id="vm-z4k" value="vm" />
</Field>
</FieldLabel>
</RadioGroup>
</FieldSet>
</FieldGroup>
</div>
</template>字段组
🌐 Field Group
将 Field 组件与 FieldGroup 堆叠。添加 FieldSeparator 来分隔它们。
🌐 Stack Field components with FieldGroup. Add FieldSeparator to divide them.
<script setup lang="ts">
import { Checkbox } from '@/components/ui/checkbox'
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
FieldSet,
} from '@/components/ui/field'
</script>
<template>
<div class="w-full max-w-md">
<FieldGroup>
<FieldSet>
<FieldLabel>Responses</FieldLabel>
<FieldDescription>
Get notified when ChatGPT responds to requests that take time, like
research or image generation.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field orientation="horizontal">
<Checkbox id="push" :default-value="true" disabled />
<FieldLabel for="push" class="font-normal">
Push notifications
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldLabel>Tasks</FieldLabel>
<FieldDescription>
Get notified when tasks you've created have updates.
<a href="#">Manage tasks</a>
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field orientation="horizontal">
<Checkbox id="push-tasks" />
<FieldLabel for="push-tasks" class="font-normal">
Push notifications
</FieldLabel>
</Field>
<Field orientation="horizontal">
<Checkbox id="email-tasks" />
<FieldLabel for="email-tasks" class="font-normal">
Email notifications
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
</FieldGroup>
</div>
</template>响应式布局
🌐 Responsive Layout
如果你使用的是 tailwindcss v3,你需要安装 @tailwindcss/container-queries
🌐 If you are in tailwindcss v3 you need to install @tailwindcss/container-queries
- 垂直字段: 默认方向将标签、控件和辅助文本垂直堆叠——非常适合移动优先布局。
- 水平字段: 在
Field上设置orientation="horizontal"以使标签和控件并排对齐。与FieldContent配合使用以保持描述对齐。 - 响应字段: 在容器感知的父元素内部设置
orientation="responsive"以实现自动列布局。在FieldGroup上应用@container/field-group类以在特定断点切换方向。
<script setup lang="ts">
import { Button } from '@/components/ui/button'
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
</script>
<template>
<div class="w-full max-w-4xl">
<form>
<FieldSet>
<FieldLegend>Profile</FieldLegend>
<FieldDescription>Fill in your profile information.</FieldDescription>
<FieldSeparator />
<FieldGroup>
<Field orientation="responsive">
<FieldContent>
<FieldLabel for="name">
Name
</FieldLabel>
<FieldDescription>
Provide your full name for identification
</FieldDescription>
</FieldContent>
<Input id="name" placeholder="Evil Rabbit" required />
</Field>
<FieldSeparator />
<Field orientation="responsive">
<FieldContent>
<FieldLabel for="lastName">
Message
</FieldLabel>
<FieldDescription>
You can write your message here. Keep it short, preferably
under 100 characters.
</FieldDescription>
</FieldContent>
<Textarea
id="message"
placeholder="Hello, world!"
required
class="min-h-[100px] resize-none sm:min-w-[300px]"
/>
</Field>
<FieldSeparator />
<Field orientation="responsive">
<Button type="submit">
Submit
</Button>
<Button type="button" variant="outline">
Cancel
</Button>
</Field>
</FieldGroup>
</FieldSet>
</form>
</div>
</template>验证与错误
🌐 Validation and Errors
- 将
data-invalid添加到Field以将整个块切换到错误状态。 - 在输入本身上添加
aria-invalid以辅助辅助技术。 - 在控件后立即渲染
FieldError或放在FieldContent内,以保持错误信息与字段对齐。
<template>
<Field data-invalid>
<FieldLabel for="email">
Email
</FieldLabel>
<Input id="email" type="email" aria-invalid />
<FieldError>Enter a valid email address.</FieldError>
</Field>
</template>可访问性
🌐 Accessibility
FieldSet和FieldLegend让相关控件保持分组,以便键盘和辅助技术用户使用。Field输出role="group",因此嵌套控件在组合时继承FieldLabel和FieldLegend的标签。- 谨慎使用
FieldSeparator,以确保屏幕阅读器能遇到清晰的章节边界。
API参考
🌐 API Reference
FieldSet
用于渲染带有间距预设的语义 fieldset 的容器。
🌐 Container that renders a semantic fieldset with spacing presets.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<template>
<FieldSet>
<FieldLegend>Delivery</FieldLegend>
<FieldGroup>
<!-- Fields -->
</FieldGroup>
</FieldSet>
</template>FieldLegend
FieldSet 的图例元素。切换到 label 变体以与标签大小对齐。
🌐 Legend element for a FieldSet. Switch to the label variant to align with label sizing.
| 属性 | 类型 | 默认值 |
|---|---|---|
variant | "legend" | "label" | "legend" |
class | string |
<FieldLegend variant="label">
Notification Preferences
</FieldLegend>FieldLegend 有两个变体:legend 和 label。label 变体适用于标签大小和对齐。如果你有嵌套的 FieldSet,这很方便。
🌐 The FieldLegend has two variants: legend and label. The label variant applies label sizing and alignment. Handy if you have nested FieldSet.
FieldGroup
布局封装器,可堆叠 Field 组件并启用容器查询以实现响应式方向。
🌐 Layout wrapper that stacks Field components and enables container queries for responsive orientations.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<template>
<FieldGroup class="@container/field-group flex flex-col gap-6">
<Field><!-- Fields --></Field>
<Field><!-- Fields --></Field>
</FieldGroup>
</template>字段
🌐 Field
单个字段的核心封装器。提供方向控制、无效状态样式和间距。
🌐 The core wrapper for a single field. Provides orientation control, invalid state styling, and spacing.
| 属性 | 类型 | 默认值 |
|---|---|---|
orientation | "vertical" | "horizontal" | "responsive" | "vertical" |
class | string | |
data-invalid | boolean |
<Field orientation="horizontal">
<FieldLabel for="remember">Remember me</FieldLabel>
<Switch id="remember" />
</Field>FieldContent
当标签位于控件旁边时,将控件和描述分组的弹性列。如果没有描述,则不需要。
🌐 Flex column that groups control and descriptions when the label sits beside the control. Not required if you have no description.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<Field>
<Checkbox id="notifications" />
<FieldContent>
<FieldLabel for="notifications">Notifications</FieldLabel>
<FieldDescription>Email, SMS, and push options.</FieldDescription>
</FieldContent>
</Field>FieldLabel
标签样式适用于直接输入和嵌套的 Field 子项。
🌐 Label styled for both direct inputs and nested Field children.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string | |
asChild | boolean | false |
<FieldLabel for="email">
Email
</FieldLabel>FieldTitle
在 FieldContent 内以标签样式呈现标题。
🌐 Renders a title with label styling inside FieldContent.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<FieldContent>
<FieldTitle>Enable Touch ID</FieldTitle>
<FieldDescription>Unlock your device faster.</FieldDescription>
</FieldContent>FieldDescription
帮助文本槽,可在水平布局中自动平衡长行。
🌐 Helper text slot that automatically balances long lines in horizontal layouts.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<FieldDescription>
We never share your email with anyone.
</FieldDescription>FieldSeparator
用于在 FieldGroup 内部分隔部分的视觉分隔符。可接受可选的内联内容。
🌐 Visual divider to separate sections inside a FieldGroup. Accepts optional inline content.
| 属性 | 类型 | 默认值 |
|---|---|---|
class | string |
<FieldSeparator>
Or continue with
</FieldSeparator>FieldError
可访问的错误容器,可接受子元素或 errors 数组(例如,来自 vee-validate)。
🌐 Accessible error container that accepts children or an errors array (e.g., from vee-validate).
| 属性 | 类型 | 默认值 |
|---|---|---|
errors | Array<{ message?: string } | undefined> | |
class | string |
<FieldError :errors="errors.username" />当 errors 数组包含多个消息时,该组件会自动渲染一个列表。
🌐 When the errors array contains multiple messages, the component renders a list automatically.
FieldError 也接受由任何实现了 标准模式 的验证器产生的问题,包括 Zod、Valibot 和 ArkType。将 schema 结果中的 issues 数组直接传递,以在各个库之间呈现统一的错误列表。