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

Vuelidate如何仅校验禁词规则绕过required校验实现表单进度保存

大表单草稿保存的校验实现方案

你现在遇到的核心问题是校验库默认聚合了所有规则(包括必填校验)的结果,$invalid状态无法直接适配草稿保存的差异化规则,不用绕着改原有校验配置,直接按下面最稳妥的方式实现:

方案1:单独抽离草稿保存专用校验逻辑(推荐,改动最小无侵入)

原有正式提交的全量校验逻辑(必填+禁用词全满足才能提交)完全保留不动,草稿保存不依赖表单的$invalid状态,单独写判断逻辑,只做「非空内容无禁用词」的校验,空值直接放行。
直接复用你现有的validations配置做递归遍历,不需要额外维护新的规则表:

// 预定义禁用词列表
const FORBIDDEN_WORDS = ['TEST1', 'TEST2']

/**
 * 草稿保存准入校验
 * @param {Object} formData 表单绑定的实际数据
 * @param {Object} validationRules 你现有写的validations配置对象
 * @returns {Boolean} true=满足保存条件 false=存在禁用词不可保存
 */
function validateDraftSave(formData, validationRules) {
  function traverse(value, ruleConf) {
    if (!ruleConf) return true

    // 处理$each配置的数组/循环对象校验场景
    if (ruleConf.$each) {
      // 空数组、空对象、null/undefined直接放行
      if (value == null) return true
      if (Array.isArray(value) && value.length === 0) return true
      if (typeof value === 'object' && Object.keys(value).length === 0) return true
      // 遍历所有子项递归校验
      for (const subItem of Object.values(value)) {
        if (!traverse(subItem, ruleConf.$each)) return false
      }
      return true
    }

    // 仅对配置了禁用词规则的字段做内容检查
    if (ruleConf.dontHaveForbiddenWords) {
      // 空字符串、null/undefined直接放行
      if (value == null) return true
      if (typeof value === 'string' && value.trim() === '') return true
      // 命中禁用词直接返回不可保存
      const hitForbidden = FORBIDDEN_WORDS.some(word => String(value).includes(word))
      if (hitForbidden) return false
    }

    // 递归遍历所有子字段的规则
    const subRuleEntries = Object.entries(ruleConf).filter(([key, val]) => !key.startsWith('$') && typeof val === 'object')
    for (const [fieldKey, subRule] of subRuleEntries) {
      if (!traverse(value?.[fieldKey], subRule)) return false
    }
    return true
  }
  return traverse(formData, validationRules)
}

使用方式很简单:草稿保存按钮的点击事件里,直接调用这个方法,传入表单数据和你现有的validations配置即可,返回true就调用保存接口,返回false就提示用户内容包含禁用词。

方案2:动态切换必填规则生效状态(适合Vuelidate/VeeValidate等支持动态规则的场景)

如果你不想单独写遍历逻辑,可以给必填规则增加场景判断,草稿保存场景下让所有required规则直接返回校验通过:

// 组件内增加状态标记,标识当前是否为草稿保存流程
const isDraftMode = ref(false)

// 重写你项目里的required校验规则
const required = (value) => {
  // 草稿模式下不校验必填
  if (isDraftMode.value) return true
  // 原有必填逻辑
  return value != null && (typeof value !== 'string' || value.trim() !== '')
}

这个方案有个注意点:触发草稿保存时要先把isDraftMode设为true,等校验库完成状态重计算后,再判断$invalid状态执行保存,保存完成后记得把isDraftMode切回false,避免影响正常的表单填写校验提示。如果表单逻辑复杂不推荐用,容易出现校验状态混乱的问题。

避坑提示

不要尝试直接修改校验实例的内部状态强行把$invalid改成false,表单字段多、迭代版本多的场景下,这类硬改内部状态的代码后续维护极容易出隐蔽bug。把草稿校验和正式提交校验的逻辑完全隔离,是长期维护成本最低的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:09:21