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