Skip to content

表单校验

@tmagic/form 字段可通过 rules 配置校验规则,兼容 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 / 默认无 typestring;若 filter: 'number' 则为 numberfilter 为自定义函数时跳过内置类型校验
display / hidden不校验
numbernumber(非 NaN)
number-range长度为 2 的数字数组
date / datetime / timevalueFormat 校验;x / timestamp 期望 number,其余按 Day.js format 严格解析字符串
daterange / timerangenames 时为长度为 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
cascadervalueSeparator 时可为 stringarray;默认 emitPath 为路径数组;emitPath: false 为叶子值;multiple 为数组;静态 options 校验路径/叶子;remote 只做形态校验
table / group-list / groupListarray
容器类(row / tab / fieldset / panel / step / flex-layout / link / component / dynamic-field 等)不校验

日期类默认 valueFormat 与字段组件一致:

  • dateYYYY/MM/DD
  • datetime / daterangeYYYY/MM/DD HH:mm:ss
  • time / timerangeHH:mm:ss

与自定义 validator 共存

同一条 rule 同时配置了 typeMatchvalidator 时,会先做类型匹配校验,通过后再执行自定义 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 包含 fieldTypemFormpropsmessage

安装时注册

ts
import MagicForm from '@tmagic/form';

app.use(MagicForm, {
  typeMatchRules: {
    'my-field': (value, { message }) => {
      if (typeof value !== 'string') {
        return message || 'my-field 应为字符串';
      }
    },
  },
});

Editor 字段内置规则

安装 @tmagic/editor 时会自动 registerTypeMatchRules 注册编辑器自定义字段规则。服务数据(数据源 / 代码块 / 节点树)未就绪时,只做基础形态校验,不做枚举或存在性失败。

字段 type期望值
key-value / style-setter普通对象;key-value + advanced 且值为 function 时放行
cond-op-select已知算子;能解析字段类型时按类型收窄
code-select-colstring;有代码块 DSL 时须为已有 codeId
page-fragment-select / ui-selectstring | number;有节点树时须为已有页面片 / 组件 id
data-source-inputstring${...} 绑定须指向已有数据源/字段
data-source-method-select[dsId, methodName],方法须在该数据源可选方法集中
data-source-field-select数据源路径 string[];有 fieldConfig 且非路径值时跳过
data-source-selectvalue: 'id' 为已有 ds id;否则为含 isBindDataSource + dataSourceId 的对象
code-select{ hookType: 'code', hookData } 的浅层结构校验(codeId 存在性 / 数据源方法存在性由内部 code-select-coldata-source-method-select 单元格各自校验,只标红出错单元格)
data-source-fields / data-source-mocks / data-source-methods数组 + 浅层结构(name/typetitle/enable/datacontent/params 等)
event-select数组;兼容新旧格式的浅层结构校验(name / 联动组件 method 是否 ∈ 可选项由字段内 eventNameConfig.rulescompActionConfig.rules 单独校验,只标红对应 select)
display-conds数组 + cond[].field/op 浅层结构校验(op 是否为已知算子、字段路径是否存在由内部 cond-op-selectfield 单元格各自校验,只标红出错单元格)

容器类字段(event-select / code-select / display-conds)遵循同一约定:容器级 typeMatch 只做结构校验,「枚举 / 存在性」下沉到内部单元格各自的 typeMatch/rules,避免单个子项非法导致整块表单标红。

业务仍可用 registerTypeMatchRule 覆盖上述任一 type。

示例

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: '宽度应为数字' }],
}

类型定义

查看 Rule 类型定义
ts
export interface Rule {
  message?: string;
  /** 系统提供的验证器类型。有:string,number,boolean,method,regexp,integer,float,array,object,enum,date,url,hex,email,any */
  type?: string;
  /** 是否按字段 config.type 校验值类型/选项匹配 */
  typeMatch?: boolean;
  /** 是否必填 */
  required?: boolean;
  trigger?: string;
  /** 自定义验证器 */
  validator?: (
    options: {
      rule: string;
      value: any;
      callback: Function;
      source: Object;
      options: {
        messages: string;
      };
    },
    data: {
      /** 表单的初始值 */
      values: FormValue;
      /** 当前作用域下的值 */
      model: FormValue;
      parent: FormValue;
      /** 整个表单的值 */
      formValue: FormValue;
      prop: string;
      config: any;
    },
    mForm: FormState | undefined,
  ) => void;
}
查看 TypeMatchValidator / TypeMatchValidateContext 类型定义
ts
/** 自定义 type 校验器:返回错误文案;通过则返回 undefined */
export type TypeMatchValidator = (value: any, context: TypeMatchValidateContext) => string | undefined;
ts
export interface TypeMatchValidateContext {
  fieldType: string;
  mForm: FormState | undefined;
  props: any;
  message?: string;
}
查看 FormInstallOptions 类型定义
ts
export interface FormInstallOptions {
  flat?: boolean;
  /** 自定义字段 type 的 typeMatch 校验规则,可覆盖内置规则或扩展业务字段 */
  typeMatchRules?: Record<string, TypeMatchValidator>;
  [key: string]: any;
}

Powered by 腾讯视频会员平台技术中心