SwFormField
SwFormField 是一个布局容器,不包含具体的输入控件,通过 default slot 放置 input、select 等原生控件或业务组件。
两种模式
| 模式 | 触发条件 | 错误来源 | scope slot field |
|---|---|---|---|
| 简单模式 | 不传 name | error prop 直接传 | 空对象 {} |
| vee-validate 模式 | 传 name(需外层 useForm()) | 自动从 schema 取 | { name, value, onInput, onChange, onBlur } |
简单模式适合:业务自行管理校验(如 onSubmit 时手动校验);vee-validate 模式适合:表单字段多、需复用 schema、需 reactive 错误提示。
基础用法(简单模式)
<SwFormField label="用户名" required hint="3-20 个字符">
<input v-model="username" type="text" />
</SwFormField>
基础表单字段
加载中...
简单模式 + 错误信息
业务侧自行校验(如 submit 时检查),通过 error prop 把错误信息传给 SwFormField 显示。
简单模式 + error prop
加载中...
vee-validate 模式
传 name 进入 vee-validate 模式,外层 useForm({ validationSchema }) 自动驱动校验。
default scope slot 暴露 field 对象,v-bind 到原生 input 即可双向绑定 + 自动校验。
<script setup lang="ts">
import { useForm } from 'vee-validate'
const { handleSubmit, errors } = useForm({
validationSchema: {
username: (v: unknown) => (typeof v === 'string' && v.length >= 3) || '至少 3 字符',
},
})
const submit = handleSubmit((values) => console.log(values))
</script>
<template>
<form @submit.prevent="submit">
<SwFormField v-slot="{ field, error }" name="username" label="用户名">
<input type="text" v-bind="field" :class="{ 'is-error': error }" />
</SwFormField>
</form>
</template>
framework 锁定
vee-validate@4.x,用函数式 schema(无需引入 yup / zod / valibot)。 业务想用 schema 库的,自行pnpm add+toTypedSchema()包装即可。
vee-validate 模式(函数式 schema)
加载中...
vee-validate 模式:异步提交 + 后端 422 错误注入
加载中...
vee-validate 模式:跨字段校验(注册场景,确认密码)
加载中...
vee-validate 模式:异步唯一性校验 + 手写 debounce
加载中...
vee-validate 模式:完整 schema(多字段类型 + form meta + 重置)
加载中...
Props
| 名称 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | — | vee-validate 字段名。传 = vee-validate 模式(错误从 schema 取);不传 = 简单模式(用 error prop) | |
label | string | — | 字段标签(label 元素文本) | |
required | boolean | false | label 后显示红色 * 星号(仅视觉,不强制校验) | |
hint | string | — | 辅助提示文字,有 error 时自动隐藏 | |
error | string | — | 直接传入错误信息(简单模式直接显示;vee-validate 模式作降级兜底——仅 schema 当前无错误时显示,不建议与 name 混用)。⚠️ 这里是文案字符串(对齐 Element 的 FormItem.error);内层 SwInput 的 error 是布尔态,联动写 :error="!!field.error" |
Slots
| 插槽名 | scope | 说明 |
|---|---|---|
default | { field, error } | 输入控件挂载点。field 在 vee-validate 模式下含 { name, value, onInput, onChange, onBlur } 可直接 v-bind;简单模式下为空对象 {}(业务用 v-model 自管)。error 是当前错误字符串(无错则空字符串) |
使用建议
- 简单模式:业务规模小、校验逻辑随手写、不打算用 schema 库时用
- vee-validate 模式:表单字段 >3、需 schema 复用、需 reactive 错误回显时用
- 避免混用:同一个
<form>内不要同时传name(vee-validate)和errorprop(简单),混用时name优先 - 复杂的上传场景使用
SwUploadImage/SwUploadVideo替代原生 input - 状态基线样式(framework#210):
.error/.required默认--destructive、.hint默认--muted-foreground、.label加粗 500——零配置即状态可辨;视觉细节项目 scoped 覆盖即可
样式定制 Token
以下 CSS 变量可在业务侧覆盖(fallback 即默认值):
| 变量 | 默认值 | 说明 |
|---|---|---|
--sw-form-field-gap | 0.375rem | label / 控件 / 错误信息之间的纵向间距 |
注意事项
- 简单模式下
field是空对象,升级 vee-validate 时极易丢绑定(Rule SF-001)—— 不传name时 slot 拿到的field为{},此时写不写v-bind="field"都不报错;等业务复杂后加上name启用 vee-validate,若忘了补v-bind="field"或显式v-model,用户输入会完全丢失且无任何运行时提示(校验永远 pass)。传了name就必须二选一绑上。 - 别同时传
name和error(Rule SF-002)—— 两套错误源并存:vee-validate 有错时显示校验错、没错时降级显示errorprop,调试时很难判断当前显示的是哪个。统一走一个来源:纯 vee-validate 用setFieldError()注入服务端错误,或干脆纯简单模式。 - 字段级错误就近显示,别用 toast(Rule UX-008)—— 这正是本组件存在的意义;校验错塞进一闪而过的 toast 用户来不及看。