Nuxt3中Vue Prime表单结合VeeValidate与Yup实现验证方案问询
问题:Nuxt3中结合Vue Prime组件实现VeeValidate表单验证
在Nuxt3项目中使用Vue Prime表单组件时,无法使用VeeValidate自带的Field组件,按官方文档操作无法实现验证功能。需要实现提交时验证和**实时验证(输入框失焦时显示错误信息)**的需求。
以下是原代码:
<template> <VForm @submit="handleAddUser" v-slot="{ values }"> <FormItem :show-separator="false"> <NuntioColorPicker @active-color="setUserColor" /> </FormItem> <FormItem :show-separator="false" label="Display name"> <InputText name="displayName" v-model="user.displayName" type="text" placeholder="Display name" /> {{ errors.displayName }} </FormItem> <FormItem :show-separator="false" label="First name"> <InputText v-model="user.firstName" type="text" placeholder="First name" /> </FormItem> <FormItem :show-separator="false" label="Last name"> <InputText v-model="user.lastName" type="text" placeholder="Last name" /> </FormItem> <FormItem :show-separator="false" label="Email"> <InputText v-model="user.email" type="text" placeholder="Email" /> </FormItem> <FormItem :show-separator="false" label="Phone"> <InputText v-model="user.phone" type="text" placeholder="Phone" /> </FormItem> <FormItem :show-separator="false" label="Password"> <InputText v-model="user.password" type="text" placeholder="Password" /> </FormItem> <pre>{{ values }}</pre> <ModalActions> <NuntioButton ghost>Cancel</NuntioButton> <NuntioButton type="primary" @click="handleAddUser">Add user</NuntioButton> <button type="submit" @click="handleAddUser">SUbmit</button> </ModalActions> </VForm> </template> <script setup lang="ts"> import FormItem from '~/components/atoms/FormItem/FormItem.vue'; import NuntioColorPicker from '~/components/molecules/NuntioColorPicker.vue'; import InputText from 'primevue/inputtext'; import ModalActions from '~/components/organisms/Modal/ModalActions.vue'; import NuntioButton from '~/components/atoms/Button/NuntioButton.vue'; import { useForm, Form as VForm } from 'vee-validate'; import * as yup from 'yup'; //TODO: Typings const user = reactive({ color: undefined, displayName: undefined, firstName: undefined, lastName: undefined, email: undefined, password: undefined, phone: undefined }); const userSchema = yup .object({ displayName: yup.string().required(), firstName: yup.string().required(), lastName: yup.string().required(), email: yup.string().email().required(), password: yup.string().required().min(6), phone: yup.string().required() }) .required(); const { validate, errors } = useForm({ validationSchema: userSchema, initialValues: user }); const setUserColor = (color: string) => { user.color = color; }; const handleAddUser = (values) => { console.log('values', values); console.log('errors', errors.value); }; </script> <style scoped lang="scss"></style>
解决方案
关键修改点
- 利用VeeValidate提供的
handleSubmit处理提交逻辑,自动触发全表单验证 - 给每个Vue Prime输入组件添加
name属性和blur事件,实现失焦实时验证 - 绑定VeeValidate的
values作为表单数据源,确保验证状态同步
修改后的完整代码
<template> <VForm v-slot="{ values }"> <FormItem :show-separator="false"> <NuntioColorPicker @active-color="setUserColor" /> </FormItem> <FormItem :show-separator="false" label="Display name"> <InputText name="displayName" v-model="values.displayName" type="text" placeholder="Display name" @blur="validateField('displayName')" /> <span class="text-red-500">{{ errors.displayName }}</span> </FormItem> <FormItem :show-separator="false" label="First name"> <InputText name="firstName" v-model="values.firstName" type="text" placeholder="First name" @blur="validateField('firstName')" /> <span class="text-red-500">{{ errors.firstName }}</span> </FormItem> <FormItem :show-separator="false" label="Last name"> <InputText name="lastName" v-model="values.lastName" type="text" placeholder="Last name" @blur="validateField('lastName')" /> <span class="text-red-500">{{ errors.lastName }}</span> </FormItem> <FormItem :show-separator="false" label="Email"> <InputText name="email" v-model="values.email" type="text" placeholder="Email" @blur="validateField('email')" /> <span class="text-red-500">{{ errors.email }}</span> </FormItem> <FormItem :show-separator="false" label="Phone"> <InputText name="phone" v-model="values.phone" type="text" placeholder="Phone" @blur="validateField('phone')" /> <span class="text-red-500">{{ errors.phone }}</span> </FormItem> <FormItem :show-separator="false" label="Password"> <InputText name="password" v-model="values.password" type="password" placeholder="Password" @blur="validateField('password')" /> <span class="text-red-500">{{ errors.password }}</span> </FormItem> <pre>{{ values }}</pre> <ModalActions> <NuntioButton ghost>Cancel</NuntioButton> <NuntioButton type="primary" @click="handleSubmit(handleAddUser)">Add user</NuntioButton> <button type="submit" @click="handleSubmit(handleAddUser)">Submit</button> </ModalActions> </VForm> </template> <script setup lang="ts"> import FormItem from '~/components/atoms/FormItem/FormItem.vue'; import NuntioColorPicker from '~/components/molecules/NuntioColorPicker.vue'; import InputText from 'primevue/inputtext'; import ModalActions from '~/components/organisms/Modal/ModalActions.vue'; import NuntioButton from '~/components/atoms/Button/NuntioButton.vue'; import { useForm, Form as VForm } from 'vee-validate'; import * as yup from 'yup'; import { watch } from 'vue'; const user = reactive({ color: undefined, displayName: undefined, firstName: undefined, lastName: undefined, email: undefined, password: undefined, phone: undefined }); const userSchema = yup .object({ displayName: yup.string().required('Display name is required'), firstName: yup.string().required('First name is required'), lastName: yup.string().required('Last name is required'), email: yup.string().email('Invalid email format').required('Email is required'), password: yup.string().required('Password is required').min(6, 'Password must be at least 6 characters'), phone: yup.string().required('Phone is required') }) .required(); const { handleSubmit, errors, validateField, values } = useForm({ validationSchema: userSchema, initialValues: user }); // 同步验证后的值到user对象 watch(values, (newValues) => { Object.assign(user, newValues); }, { deep: true }); const setUserColor = (color: string) => { user.color = color; }; const handleAddUser = (validatedValues) => { // 验证通过后执行业务逻辑 console.log('Validated values:', validatedValues); console.log('User data:', user); }; </script> <style scoped lang="scss"></style>
功能说明
- 实时验证:通过
@blur="validateField('字段名')"在输入框失焦时触发单个字段的验证,即时显示错误提示 - 提交验证:使用
handleSubmit包裹提交方法,只有全表单验证通过后才会执行后续逻辑,避免无效提交 - 状态同步:通过watch监听VeeValidate的
values,同步到自定义的user对象,确保业务数据和表单状态一致
内容的提问来源于stack exchange,提问作者envy
相关产品推荐
相关产品推荐

