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
相关产品推荐
相关产品推荐

