Vue3 + Vee Validate4:验证选中数组长度以阻止空表单提交
解决Vue3 + Vee Validate4中选中数组的提交验证问题
为啥之前的方法不生效
你之前用watch监听selected数组后调用validate,但这个验证是独立于表单体系的,Vee Validate的Form组件无法识别这个验证结果,所以哪怕数组为空,点击提交还是会触发onSubmit。
正确实现方式
要让selected的验证成为表单整体验证的一部分,需要把它注册为表单字段,通过Vee Validate的表单管理机制处理验证。以下是完整的修改方案:
修改后的代码
<template> <Form @submit="onSubmit"> <!-- 其他已正常验证的字段 --> <!-- 选择项操作区域 --> <div class="selection-area"> <h3>未选中列表</h3> <div v-for="item in unselected" :key="item.id"> <button @click="moveToSelected(item)">选择 {{ item.title }}</button> </div> <h3>已选中列表</h3> <div v-for="item in selected" :key="item.id"> <button @click="moveToUnselected(item)">取消选择 {{ item.title }}</button> </div> </div> <!-- 显示选中数组的验证错误 --> <p class="error">{{ errors['selected'] }}</p> <button type="submit">提交</button> </Form> </template> <script setup> import { ref, watch } from 'vue'; import { Form, useForm, defineRule } from 'vee-validate'; // 注册自定义验证规则(如果已在其他文件注册可省略) defineRule('arrayLength', (array) => { if (array.length < 1) { return '请至少选择1项'; } return true; }); const unselected = ref([ { title: 'Bram janssen', id: 1, value: 1 }, { title: 'Bert Bertsma', id: 2, value: 2 }, { title: 'Kees Keesma', id: 3, value: 3 }, { title: 'Jan Janssen', id: 4, value: 4 }, { title: 'Pieter Pietersma', id: 5, value: 5 }, { title: 'Lars Klaver', id: 6, value: 6 }, ]); const selected = ref([]); // 初始化表单,将selected注册为表单字段并绑定验证规则 const { handleSubmit, errors, form } = useForm({ initialValues: { selected: selected.value, }, rules: { selected: 'arrayLength', // 应用自定义验证规则 }, }); // 同步selected数组和表单字段的变化(深度监听数组内容) watch(selected, (newSelected) => { form.setValue('selected', [...newSelected]); }, { deep: true }); // 移动选中项的逻辑 const moveToSelected = (item) => { const idx = unselected.value.findIndex(i => i.id === item.id); if (idx !== -1) { unselected.value.splice(idx, 1); selected.value.push(item); } }; const moveToUnselected = (item) => { const idx = selected.value.findIndex(i => i.id === item.id); if (idx !== -1) { selected.value.splice(idx, 1); unselected.value.push(item); } }; // 提交函数:只有所有验证通过才会执行内部逻辑 const onSubmit = handleSubmit((formValues) => { console.log('表单提交成功,选中项:', formValues.selected); // 在这里编写你的表单提交逻辑 }); </script> <style scoped> .error { color: red; } </style>
关键要点
- 表单字段绑定:通过
useForm将selected注册为表单字段,让Vee Validate把它纳入整体验证流程。 - 自动验证拦截:
handleSubmit会在提交前自动验证所有字段,包括selected,如果数组为空(验证失败),会直接阻止提交逻辑执行,并返回错误信息。 - 错误提示:通过
errors对象可以获取selected字段的验证错误,用来给用户提示。
更简洁的写法(无需单独的selected ref)
如果你不想维护单独的selected ref,可以直接使用表单的values来管理选中项,省去同步步骤:
// 去掉单独的selected ref,直接用表单的values const { handleSubmit, errors, values } = useForm({ initialValues: { selected: [], }, rules: { selected: 'arrayLength', }, }); // 移动逻辑改为操作values.selected const moveToSelected = (item) => { const idx = unselected.value.findIndex(i => i.id === item.id); if (idx !== -1) { unselected.value.splice(idx, 1); values.selected.push(item); } }; const moveToUnselected = (item) => { const idx = values.selected.findIndex(i => i.id === item.id); if (idx !== -1) { values.selected.splice(idx, 1); unselected.value.push(item); } };
内容的提问来源于stack exchange,提问作者Bram Janssen
相关产品推荐
相关产品推荐

