跳到主要內容

Form 表單

由 LhForm + LhFormItem 組成的複合元件,提供資料驗證、錯誤提示、標籤對齊等能力。

基礎用法​

驗證表單
import { useRef, useState } from 'react'
import { LhButton, LhForm, LhFormItem, LhInput, LhSelect } from '@lh-ui/react'
import type { LhFormInstance, LhFormRule } from '@lh-ui/react'

interface FormData {
name: string
style: string
}

const rules: Record<string, LhFormRule[]> = {
name: [{ required: true, message: '请输入作品名称', trigger: 'blur' }],
style: [{ required: true, message: '请选择画风', trigger: 'change' }],
}

export default function Demo() {
const [formData, setFormData] = useState<FormData>({ name: '', style: '' })
const formRef = useRef<LhFormInstance>(null)

const handleSubmit = async () => {
const valid = await formRef.current?.validate()
if (valid) alert(`提交成功:${formData.name} / ${formData.style}`)
}

const handleReset = () => {
formRef.current?.resetFields()
setFormData({ name: '', style: '' })
}

return (
<LhForm ref={formRef} model={formData} rules={rules} labelWidth="80px">
<LhFormItem label="作品名称" prop="name">
<LhInput
value={formData.name}
onChange={(val) => setFormData((prev) => ({ ...prev, name: val }))}
/>
</LhFormItem>
<LhFormItem label="画风" prop="style">
<LhSelect
value={formData.style}
onChange={(val) => setFormData((prev) => ({ ...prev, style: val as string }))}
options={[{ label: '水墨', value: 'ink' }]}
/>
</LhFormItem>
<LhFormItem>
<LhButton type="primary" onClick={handleSubmit}>提交</LhButton>
<LhButton onClick={handleReset}>重設</LhButton>
</LhFormItem>
</LhForm>
)
}

Form Props​

屬性說明型別預設值
model表單資料物件(必填)Record<string, unknown>—
rules驗證規則,鍵為欄位名Record<string, LhFormRule[]>—
labelWidth標籤寬度string | number—
labelPosition標籤位置'left' | 'right' | 'top''right'
inline行內版面配置booleanfalse
disabled停用全部子項booleanfalse
size子項尺寸'large' | 'middle' | 'small'跟隨 ConfigProvider
onSubmit原生提交事件(已 preventDefault)(event: FormEvent) => void—

FormItem Props​

屬性說明型別預設值
label標籤文案string—
prop欄位名(支援點號路徑,對應 model 的鍵)string—
rulesitem 級規則(同名時覆蓋 form 級)LhFormRule[]—
required必填星號(僅渲染標記,驗證語意由 rules 提供)booleanfalse
labelWidth覆蓋 form 級標籤寬度string | number—
errorMessage自訂錯誤訊息string—
showMessage顯示錯誤提示booleantrue

LhFormRule​

屬性說明型別
required是否必填boolean
message驗證失敗訊息string
trigger觸發方式'blur' | 'change'
validator自訂驗證函式(可傳回 Promise,非同步驗證會正確等待)(value, model) => string | undefined | Promise<string | undefined>
min / max最小 / 最大值(數字或長度)number
pattern正規驗證RegExp

Form ref 方法​

LhFormInstance(透過 forwardRef + useImperativeHandle 暴露):

方法說明傳回值
validate驗證全部欄位Promise<boolean>
validateField驗證單一欄位Promise<boolean>
resetFields重設全部欄位到初始值void
resetField重設單一欄位void
const formRef = useRef<LhFormInstance>(null)
const ok = await formRef.current?.validate()
非同步驗證

本庫修正了 plus 的非同步驗證缺陷:plus 的 validateField 用 Promise.resolve(!message) 不會等待非同步 validator 的 Promise,非同步驗證恆傳回 true。React 版顯式等待 thenable 完成後再判定。詳見遷移指南。

欄位註冊

LhFormItem 在 useEffect 內向 form 註冊驗證器,卸載時自動註銷。欄位無需預先宣告在 rules 裡——rules 裡沒有但 model 裡有的欄位,初始值會在註冊時補拍。

trigger 的語意(React 增強)

share 的 validateFormField 不解釋 trigger,觸發時機由本層接線:trigger: 'blur'(預設) 隨 FormItem 失焦驗證,trigger: 'change' 隨內容區 change 驗證。未標註 trigger 的規則 只在失焦與 validate() 時運行,輸入過程中不會反覆報錯。

change 驗證取事件目標的新值而非 model 快照——React 的狀態更新與事件派發不在同一拍, 回頭讀 model 會滯後一拍。原生控制元件(input / textarea / 原生 select)的 change 事件 冒泡到內容區即被擷取;自訂控制元件沒有原生 change 事件(LhSelect 的選項點選只產生 click), 透過 FormItem 上下文的 validateChange(value) 主動帶著新值觸發。

重設清錯誤(React 增強)

resetFields() 除了把 model 還原到初始值快照,還會自增內部 resetVersion,各 FormItem 監聽到版本變化即清空自身錯誤態。外部受控狀態仍需自行同步(如 demo 裡的 setFormData(initial))——React 無法像 Vue 的 reactive 鏈路那樣代寫 model。

樣式​

import '@lh-ui/react/style/form'