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 使用者來不及看。