Skip to content

[t-form] [Feature Request] 支持通过 schema 属性接入 Zod 校验,简化 rules 定义 #6709

@SnhAenIgseAl

Description

@SnhAenIgseAl

这个功能解决了什么问题

背景

目前 t-form 使用 rules 数组进行字段校验,当字段有多个规则(如必填、长度、格式、自定义)时,代码较为冗长且难以复用。

建议

新增 schema 属性,允许传入一个校验 schema(例如 Zod 的 z.Schema)。组件内部执行校验并返回结果。
对于需要精细控制提示触发时机(trigger)或提示样式类型(type)的场景,仍可继续使用 rules

示例对比

现有写法(rules)
const rules: FormProps['rules'] = {
  account: [
    {
      required: true,
      message: '姓名必填',
      type: 'error',
      trigger: 'blur',
    },
    {
      required: true,
      message: '姓名必填',
      type: 'error',
      trigger: 'change',
    },
    {
      whitespace: true,
      message: '姓名不能为空',
    },
    {
      min: 3,
      message: '输入字数应在3到6之间',
      type: 'error',
      trigger: 'blur',
    },
    {
      max: 6,
      message: '输入字数应在3到6之间',
      type: 'error',
      trigger: 'blur',
    },
  ],
  password: [
    {
      required: true,
      message: '密码必填',
      type: 'error',
    },
  ],
  email: [
    {
      required: true,
      message: '邮箱必填',
      type: 'error',
    },
    {
      email: { ignore_max_length: true },
      message: '格式必须为邮箱',
      type: 'error',
    },
  ],
  age: [
    {
      required: true,
      message: '年龄必填',
      type: 'error',
    },
    {
      number: true,
      message: '请输入数字',
      type: 'warning',
    },
  ],
  gender: [
    {
      required: true,
      message: '性别必填',
      type: 'warning',
    },
  ],
  course: [
    {
      required: true,
      message: '课程必填',
      type: 'warning',
    },
  ],
  college: [
    // 注意:trigger: blur 仅在输入框或选择框失去焦点时触发,需要注意配合 trigger: change 使用
    {
      required: true,
      message: '学院必选',
      type: 'warning',
      trigger: 'blur',
    },
    {
      required: true,
      message: '学院必选',
      type: 'warning',
      trigger: 'change',
    },
  ],
  'content.url': [
    {
      required: true,
      message: '个人网站必填',
      type: 'warning',
    },
    {
      url: {
        protocols: ['http', 'https', 'ftp'],
        require_protocol: true,
      },
      message: '请输入正确的个人主页',
    },
  ],
};
使用 schema
const formSchema = z.object({
  account: z.string()
    .nonempty({ error: '姓名必填' })
    .min(3, { error: '输入字数应在3到6之间' })
    .max(6, { error: '输入字数应在3到6之间' }),
  password: z.string().nonempty({ error: '密码必填' }),
  email: z.email({ error: '格式必须为邮箱' }),
  age: z.number().int().min(0, '年龄必须为非负整数'),
  gender: z.string().nonempty({ error: '性别必填' }),
  course: z.string().nonempty({ error: '课程必填' }),
  college: z.string().nonempty({ error: '学院必选' }),
  content: z.object({
    url: z.url({ error: '请输入正确的个人主页(支持 http/https/ftp)' })
  }),
});

自定义校验规则

使用 .refine() 方法,例如校验二次密码是否一致

const passwordSchema = z.object({
  password: z.string().min(8, "密码至少需要8位"),
  confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
  message: "两次输入的密码不一致",
  path: ["confirmPassword"],
});

你建议的方案是什么

希望 t-form 组件在保留原先校验引擎的基础上增加 schema property 以简化表单校验使用,例如

<t-form ref="formRef" :data="data" :schema="formSchema">
  ……
<t-form />

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions