mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-07-14 07:07:08 +08:00
184 lines
5.3 KiB
Markdown
184 lines
5.3 KiB
Markdown
# 表单校验
|
||
|
||
`@tmagic/form` 字段可通过 `rules` 配置校验规则,兼容 [async-validator](https://github.com/yiminghe/async-validator)(Element Plus 内部使用)的常见能力,并额外支持按字段 `type` 做值类型 / 选项匹配校验(`typeMatch`)。
|
||
|
||
## 基础用法
|
||
|
||
```ts
|
||
{
|
||
name: 'title',
|
||
text: '名称',
|
||
rules: [
|
||
{ required: true, message: '请输入名称' },
|
||
{ typeMatch: true, message: '名称类型不合法' },
|
||
],
|
||
}
|
||
```
|
||
|
||
`rules` 类型见下方 [`Rule`](#类型定义)。未配置 `typeMatch` 时,现有表单行为不变。
|
||
|
||
## typeMatch
|
||
|
||
开启 `typeMatch: true` 后,表单会按字段 `config.type`(及关联配置)校验当前值是否合法。空值(`undefined` / `null` / `''`,多选类空数组 `[]`)直接通过,必填请继续使用 `required`。
|
||
|
||
### 内置映射
|
||
|
||
| 字段 type | 期望值 |
|
||
| --- | --- |
|
||
| `text` / `textarea` / `color-picker` / `html` / 默认无 type | `string`;若 `filter: 'number'` 则为 `number`;`filter` 为自定义函数时跳过内置类型校验 |
|
||
| `display` / `hidden` | 不校验 |
|
||
| `number` | `number`(非 NaN) |
|
||
| `number-range` | 长度为 2 的数字数组 |
|
||
| `date` / `datetime` / `time` | 按 `valueFormat` 校验;`x` / `timestamp` 期望 `number`,其余按 [Day.js format](https://day.js.org/docs/en/display/format) 严格解析字符串 |
|
||
| `daterange` / `timerange` | 无 `names` 时为长度为 2 的数组,元素按 `valueFormat` 校验;有 `names` 时跳过 |
|
||
| `switch` / `checkbox` | 值必须是解析后的 `activeValue` / `inactiveValue` 之一(显式配置优先;未配置且 `filter === 'number'` 时为 `1`/`0`;否则为 `true`/`false`) |
|
||
| `select` | 单选:值 ∈ options;`multiple`:数组且每项 ∈ options;`allowCreate` / `remote`:只校验基础形态,不做 options 枚举 |
|
||
| `radio-group` / `radioGroup` | 值 ∈ options |
|
||
| `checkbox-group` / `checkboxGroup` | 数组且每项 ∈ options |
|
||
| `cascader` | 有 `valueSeparator` 时可为 `string` 或 `array`;默认 `emitPath` 为路径数组;`emitPath: false` 为叶子值;`multiple` 为数组;静态 options 校验路径/叶子;`remote` 只做形态校验 |
|
||
| `table` / `group-list` / `groupList` | `array` |
|
||
| 容器类(`row` / `tab` / `fieldset` / `panel` / `step` / `flex-layout` / `link` / `component` / `dynamic-field` 等) | 不校验 |
|
||
|
||
日期类默认 `valueFormat` 与字段组件一致:
|
||
|
||
- `date`:`YYYY/MM/DD`
|
||
- `datetime` / `daterange`:`YYYY/MM/DD HH:mm:ss`
|
||
- `time` / `timerange`:`HH:mm:ss`
|
||
|
||
### 与自定义 validator 共存
|
||
|
||
同一条 rule 同时配置了 `typeMatch` 与 `validator` 时,会先做类型匹配校验,通过后再执行自定义 `validator`。
|
||
|
||
```ts
|
||
{
|
||
name: 'age',
|
||
type: 'number',
|
||
rules: [
|
||
{
|
||
typeMatch: true,
|
||
message: '年龄必须是数字',
|
||
validator: ({ value, callback }) => {
|
||
if (value < 0) {
|
||
callback(new Error('年龄不能小于 0'));
|
||
return;
|
||
}
|
||
callback();
|
||
},
|
||
},
|
||
],
|
||
}
|
||
```
|
||
|
||
## 扩展自定义 type 规则
|
||
|
||
业务可覆盖内置规则,或为自定义字段 type 注册校验。自定义规则优先于内置规则。
|
||
|
||
### 运行时注册
|
||
|
||
```ts
|
||
import {
|
||
registerTypeMatchRule,
|
||
registerTypeMatchRules,
|
||
deleteTypeMatchRule,
|
||
clearTypeMatchRules,
|
||
} from '@tmagic/form';
|
||
|
||
// 覆盖内置 text
|
||
registerTypeMatchRule('text', (value, { message }) => {
|
||
if (typeof value !== 'string') {
|
||
return message || '值类型应为字符串';
|
||
}
|
||
});
|
||
|
||
// 扩展业务字段
|
||
registerTypeMatchRule('vs-code', (value, { message }) => {
|
||
if (typeof value !== 'string') {
|
||
return message || '代码字段应为字符串';
|
||
}
|
||
});
|
||
|
||
// 批量注册
|
||
registerTypeMatchRules({
|
||
foo: (value) => (Array.isArray(value) ? undefined : '应为数组'),
|
||
});
|
||
|
||
// 删除 / 清空
|
||
deleteTypeMatchRule('foo');
|
||
clearTypeMatchRules();
|
||
```
|
||
|
||
自定义校验器签名:`(value, context) => string | undefined`。返回错误文案表示失败,返回 `undefined` 表示通过。`context` 包含 `fieldType`、`mForm`、`props`、`message`。
|
||
|
||
### 安装时注册
|
||
|
||
```ts
|
||
import MagicForm from '@tmagic/form';
|
||
|
||
app.use(MagicForm, {
|
||
typeMatchRules: {
|
||
'my-field': (value, { message }) => {
|
||
if (typeof value !== 'string') {
|
||
return message || 'my-field 应为字符串';
|
||
}
|
||
},
|
||
},
|
||
});
|
||
```
|
||
|
||
## 示例
|
||
|
||
### select 选项匹配
|
||
|
||
```ts
|
||
{
|
||
name: 'status',
|
||
type: 'select',
|
||
options: [
|
||
{ text: '启用', value: 1 },
|
||
{ text: '禁用', value: 0 },
|
||
],
|
||
rules: [
|
||
{ required: true, message: '请选择状态' },
|
||
{ typeMatch: true, message: '状态值不合法' },
|
||
],
|
||
}
|
||
```
|
||
|
||
### date 按 valueFormat 校验
|
||
|
||
```ts
|
||
{
|
||
name: 'birthday',
|
||
type: 'date',
|
||
valueFormat: 'YYYY-MM-DD',
|
||
rules: [{ typeMatch: true, message: '日期格式不正确' }],
|
||
}
|
||
```
|
||
|
||
### text + filter: number
|
||
|
||
```ts
|
||
{
|
||
name: 'width',
|
||
type: 'text',
|
||
filter: 'number',
|
||
rules: [{ typeMatch: true, message: '宽度应为数字' }],
|
||
}
|
||
```
|
||
|
||
## 类型定义
|
||
|
||
::: details 查看 Rule 类型定义
|
||
<<< @/../packages/form-schema/src/base.ts#Rule{ts}
|
||
:::
|
||
|
||
::: details 查看 TypeMatchValidator / TypeMatchValidateContext 类型定义
|
||
<<< @/../packages/form/src/utils/typeMatch.ts#TypeMatchValidator{ts}
|
||
|
||
<<< @/../packages/form/src/utils/typeMatch.ts#TypeMatchValidateContext{ts}
|
||
:::
|
||
|
||
::: details 查看 FormInstallOptions 类型定义
|
||
<<< @/../packages/form/src/plugin.ts#FormInstallOptions{ts}
|
||
:::
|