返回

Vue 3 TypeScript 中的条件验证:如何处理带有条件值的计算值

vue.js

在 Vue 3 TypeScript 中使用 Yup 进行带有条件值的条件验证

引言

在构建响应式和可验证的表单时,使用条件验证非常重要。在 Vue 3 TypeScript 中,我们可以利用 Yup 库来轻松实现此目的。然而,对于使用计算值作为条件的情况,事情可能会变得棘手。本文将探讨如何使用 Yup 对计算值进行条件验证,并提供逐步的解决方法。

问题

假设我们有一个计算值 isVerifiedPhone,它表示用户的电话号码是否已验证。我们希望仅当 isVerifiedPhone 为 true 时,电子邮件字段才需要填写。然而,使用传统的 Yup 模式,在 useForm 钩子函数内对 isVerifiedPhone 的引用不会更新。

尝试过的解决方案

我们尝试了几种方法来解决这个问题:

  • 使用 yup.string().email('Enter Email').default('').when(isVerifiedPhone.value, { ... }),但遇到了 is 属性的错误。
  • 使用 yup.string().email('Enter Email').default('').when([], { is: () => isVerifiedPhone.value, ... }),也遇到了 is 属性的错误。

解决方案

要实现带有条件值的条件验证,我们可以使用 lazy 方法:

email: yup
  .string()
  .email('Enter Email')
  .default('')
  .when('phone', (phone, schema) =>
    isVerifiedPhone.value ? schema.required('Enter Email') : schema
  ),

lazy 方法允许我们传递一个函数,该函数接收要验证的字段(phone)和一个模式构建器函数(schema)。该函数返回更新后的模式。在我们的示例中,如果 phone 有效(isVerifiedPhone.value 为 true),我们要求电子邮件字段填写,否则我们允许它为空。

实施

在 Vue 3 组件中,我们可以使用 useForm 钩子函数实现条件验证:

import { useForm } from 'vee-validate';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';

const schema = yup.object({
  phone: yup
    .string()
    .default('')
    .required('Enter Phone Number')
    .length(10, 'Phone Number should include 10 digits'),
  email: yup
    .string()
    .email('Enter Email')
    .default('')
    .when('phone', (phone, schema) =>
      isVerifiedPhone.value ? schema.required('Enter Email') : schema
    ),
});

const { errors, submit } = useForm({
  resolver: yupResolver(schema),
  defaultValues: {
    phone: userPhone.value,
    email: userEmail.value,
  },
});

结论

使用 lazy 方法,我们能够有效地使用 Yup 对计算值进行条件验证。这使得我们可以构建健壮且响应性强的表单,确保用户提供所有必要的输入。

常见问题解答

  1. 为什么不使用 yup.mixed().test()

    • yup.mixed().test() 用于自定义验证,它需要一个同步函数。使用 lazy 方法提供了更优雅和更易于维护的解决方案。
  2. lazy 方法是否支持异步验证?

    • 不,lazy 方法不支持异步验证。如果您需要执行异步验证,可以使用 yup.object().when() 方法。
  3. 为什么 isVerifiedPhone 的引用在 useForm 内不会更新?

    • useForm 钩子函数内部,表单状态是一个反应对象。任何对计算值的更改都不会触发反应性更新。因此,我们需要使用 lazy 方法来手动传递当前 isVerifiedPhone 值。
  4. 是否可以对多个字段应用条件验证?

    • 是的,您可以通过将 lazy 函数传递给多个字段来对多个字段应用条件验证。
  5. 如何处理嵌套对象中的条件验证?

    • 对于嵌套对象,您可以使用 yup.reach() 方法来访问嵌套字段并应用条件验证。