表单组件示例
演示 src/common/components/forms 下的 6 个组件:校验表单组件与表格搜索组件。
搜索组件
SearchInput 与 SearchSelect 把条件写入搜索 state。
{}校验表单组件
ValidatableInput / ValidatableSelect / ValidatableDate / ValidatableTextarea,配合 react-hook-form 使用。
表单组件(components/forms)使用说明
概述
src/common/components/forms/ 目录包含 6 个通用表单组件,基于 react-hook-form 与 shadcn/ui 构建,分为两大类:
- 校验表单组件(配合
react-hook-form的register/setValue):ValidatableInput、ValidatableSelect、ValidatableDate、ValidatableTextarea - 表格搜索组件(把条件写入搜索 state):
SearchInput、SearchSelect
两者都用
pageTranslate翻译字段 label;下拉组件内部还会用useTranslations("KVS")翻译字典项的显示文本。
ValidatableInput — 校验输入框
受控校验输入框,通过 forwardRef 配合 register("fieldName") 使用,{...register(...)} 会把 onChange / onBlur / name / ref 透传到内部 <input>。
import {ValidatableInput} from "@/common/components/forms/validatable-input";
const {register, formState: {errors, isSubmitted}} = useForm();
<ValidatableInput
{...register("userName", {required: "必填"})}
type="text"
fieldPropertyName="userName"
pageTranslate={pageTranslate}
errorMessage={errors.userName?.message}
isSubmitted={isSubmitted}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| fieldPropertyName | string | 是 | 字段名(同时作为 label 翻译 key 与 input name) |
| type | "text" | "password" | "email" |
| pageTranslate | (key) => string | 否 | 字段 label 翻译函数 |
| validateTranslate | (key) => string | 否 | 校验文案翻译函数(供外层校验用) |
| errorMessage | string | 否 | 校验错误文案(一般取 errors.xxx?.message) |
| isSubmitted | boolean | 否 | 是否已提交,用于在合法字段后显示绿色对勾 |
| readonly | boolean | 否 | 是否只读 |
其余属性继承 React.InputHTMLAttributes(含 defaultValue、className 等)。
ValidatableSelect — 校验下拉框
使用 setValue 而非 register 同步值,dictionary 传入 KeyValue[];未命中默认值时会回退到字典第一项。
import {ValidatableSelect} from "@/common/components/forms/validatable-select";
<ValidatableSelect
fieldPropertyName="gender"
dictionary={dictionary}
defaultValue={original.gender}
setValue={setValue}
pageTranslate={pageTranslate}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| fieldPropertyName | string | 是 | 字段名 |
| dictionary | KeyValue[] | 是 | 下拉选项字典 |
| setValue | (name, value) => void | 是 | react-hook-form 的 setValue |
| defaultValue | any | 否 | 初始值(字典 key) |
| pageTranslate | (key) => string | 否 | 字段 label 翻译函数 |
| className | string | 否 | 触发器样式 |
KeyValue 定义:{ key: string; value: string },key 为提交值,value 既是显示文本、也作为 KVS 翻译 key(KVS.<字段>.<value>),需与 messages 里的 KVS 键保持一致。
ValidatableDate — 校验日期
基于 Calendar + Popover 的日期选择,内部用 dayjs 格式化,setValue 同步值;挂载时用 useEffect 写入默认值(默认今天)。
import {ValidatableDate} from "@/common/components/forms/validatable-date";
<ValidatableDate
fieldPropertyName="birthday"
defaultValue="1990-01-01"
format="YYYY-MM-DD"
setValue={setValue}
pageTranslate={pageTranslate}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| fieldPropertyName | string | 是 | 字段名 |
| setValue | (name, value) => void | 是 | 日期变化时回写 |
| defaultValue | string | 否 | 初始日期字符串,默认今天 |
| format | string | 否 | dayjs 格式,默认 YYYY-MM-DD |
| pageTranslate | (key) => string | 否 | 字段 label 翻译函数 |
| readonly | boolean | 否 | 只读 |
ValidatableTextarea — 校验多行文本
与 ValidatableInput 用法一致,通过 register 接入,渲染 shadcn 的 Textarea。
import {ValidatableTextarea} from "@/common/components/forms/validatable-textarea";
<ValidatableTextarea
{...register("description")}
fieldPropertyName="description"
pageTranslate={pageTranslate}
errorMessage={errors.description?.message}
isSubmitted={isSubmitted}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| fieldPropertyName | string | 是 | 字段名 |
| pageTranslate | (key) => string | 否 | 字段 label 翻译函数 |
| errorMessage | string | 否 | 校验错误文案 |
| isSubmitted | boolean | 否 | 是否已提交 |
| readonly | boolean | 否 | 只读 |
其余属性继承 React.TextareaHTMLAttributes。
SearchInput — 搜索输入框
用于表格搜索栏,把输入写入 setSearchCondition 的对应字段。
import SearchInput from "@/common/components/forms/search-input";
<SearchInput
value={condition.userName || ""}
propertyName="userName"
pageTranslate={pageTranslate}
setSearchCondition={setCondition}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| value | string | 否 | 受控值 |
| propertyName | string | 是 | 字段名 |
| pageTranslate | (key) => string | 是 | 占位符翻译函数 |
| setSearchCondition | Dispatch<SetStateAction<T>> | 是 | 回写搜索条件 state |
SearchSelect — 搜索下拉框
用于表格搜索栏,除字典项外自动追加一个「全部」(value 为 -1)选项。
import SearchSelect from "@/common/components/forms/search-select";
<SearchSelect
propertyName="status"
pageTranslate={pageTranslate}
setSearchCondition={setCondition}
dictionary={dictionary}
/>
| Prop | 类型 | 必填 | 说明 |
|---|---|---|---|
| propertyName | string | 是 | 字段名 |
| setSearchCondition | Dispatch<SetStateAction<T>> | 是 | 回写搜索条件 state |
| dictionary | KeyValue[] | 否 | 下拉选项字典 |
| pageTranslate | (key) => string | 是 | 占位符翻译函数 |
集成约定
- register 类组件(
ValidatableInput/ValidatableTextarea):{...register("field")}展开接入,errorMessage={errors.field?.message}。 - setValue 类组件(
ValidatableSelect/ValidatableDate):不注册,直接传setValue与defaultValue。 - 下拉字典的
value会先尝试用KVS.<field>.<value>翻译,缺失则原样显示,所以需在 messages 里补充KVS命名空间。