You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Yup验证规则在页面初始加载时校验必填日期字段?

解决Yup必填校验页面加载时立即触发错误提示的问题

问题描述

我定义了一个计算属性fromSchema,根据props.required生成Yup的必填或非必填校验规则:

const fromSchema = computed(() => {
   return props.required
     ? yup.mixed().required(t('this text field is required', [props.fromDateName]))    
     : yup.mixed().notRequired()
})

页面加载时,.required()会立即校验目标日期选择器字段,导致错误信息一开始就显示。尝试过使用onMount()、onClick(),但onClick不符合需求(需要点击日期选择器时才显示错误),且该常量未置于onLoad或document.Ready中。另外必须用<FieldError :key="errorMessage" :message="errorMessage" />标签展示错误,无法使用@blur方法。请问应如何修改yup.mixed().required(t('message.error.ECM119', [props.fromDateName]))来解决该问题?

解决方案

方法一:自定义Yup校验规则,延迟校验触发时机

通过Yup的test方法自定义校验逻辑,让必填校验仅在字段被触碰(比如用户点击过日期选择器)后才执行,避免页面初始化时就触发错误。

修改后的代码:

const fromSchema = computed(() => {
  if (!props.required) {
    return yup.mixed().notRequired();
  }

  return yup.mixed().test({
    name: 'required',
    message: t('message.error.ECM119', [props.fromDateName]),
    test: function(value) {
      // 获取字段是否被触碰的状态(根据实际使用的表单库调整逻辑)
      // 以常见表单库为例,通常会在上下文或表单状态中记录`touched`属性
      const isTouched = this.options.context?.touched?.[this.path] || false;
      
      // 未触碰时直接通过校验,触碰后再检查是否为空
      if (!isTouched) return true;
      return value !== undefined && value !== null;
    }
  });
});

方法二:控制错误提示的显示时机

如果无法修改校验规则,可以在FieldError组件中添加判断,仅当字段被触碰后才渲染错误信息:

<FieldError 
  :key="errorMessage" 
  :message="errorMessage" 
  v-if="formState.touched.fromDate" <!-- 替换为实际表单中记录字段触碰状态的属性 -->
/>

关键说明

  • 核心逻辑是延迟必填校验的触发时机,避免页面初始化阶段就执行校验。
  • 不同表单库(如VeeValidate、Formik等)记录字段触碰状态的方式不同,需要根据实际使用的库调整isTouched的判断逻辑。
  • 如果表单库未提供触碰状态,可以手动在日期选择器的点击事件中标记字段为已触碰,再结合自定义校验判断。

内容的提问来源于stack exchange,提问作者Hadrian Clayton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:39:55