SwFormField

SwFormField 是一个布局容器,不包含具体的输入控件,通过 default slot 放置 input、select 等原生控件或业务组件。

两种模式

模式触发条件错误来源scope slot field
简单模式不传 nameerror 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

名称类型必填默认值说明
namestring—vee-validate 字段名。传 = vee-validate 模式(错误从 schema 取);不传 = 简单模式(用 error prop)
labelstring—字段标签(label 元素文本)
requiredbooleanfalselabel 后显示红色 * 星号(仅视觉,不强制校验)
hintstring—辅助提示文字,有 error 时自动隐藏
errorstring—直接传入错误信息(简单模式直接显示;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)和 error prop(简单),混用时 name 优先
  • 复杂的上传场景使用 SwUploadImage / SwUploadVideo 替代原生 input
  • 状态基线样式(framework#210):.error / .required 默认 --destructive、.hint 默认 --muted-foreground、.label 加粗 500——零配置即状态可辨;视觉细节项目 scoped 覆盖即可

样式定制 Token

以下 CSS 变量可在业务侧覆盖(fallback 即默认值):

变量默认值说明
--sw-form-field-gap0.375remlabel / 控件 / 错误信息之间的纵向间距

注意事项

  • 简单模式下 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 有错时显示校验错、没错时降级显示 error prop,调试时很难判断当前显示的是哪个。统一走一个来源:纯 vee-validate 用 setFieldError() 注入服务端错误,或干脆纯简单模式。
  • 字段级错误就近显示,别用 toast(Rule UX-008)—— 这正是本组件存在的意义;校验错塞进一闪而过的 toast 用户来不及看。