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

如何用VeeValidate 4结合Zod验证密码与确认密码字段?

解决VeeValidate + Zod跨组件验证密码一致性问题

核心思路

VeeValidate的useForm全局管理整个表单状态,不管字段拆分到哪个子组件,只要绑定对应字段名(name),顶层验证Schema就能获取所有字段值,结合Zod的refine方法即可实现跨字段的密码一致性验证。

步骤1:编写带跨字段验证的Zod Schema

重点在Zod对象的refine方法中比较密码与确认密码,并通过path将错误信息绑定到确认密码字段,确保错误提示精准对应:

// schemas.js
import { z } from 'zod';

export const formSchema = z.object({
  password: z.string().min(8, '密码长度不能少于8位'),
  'confirm-password': z.string().min(8, '确认密码长度不能少于8位')
}).refine(
  (data) => data.password === data['confirm-password'],
  {
    message: '两次输入的密码不一致',
    path: ['confirm-password'] // 将错误关联到确认密码字段
  }
);

步骤2:父组件配置useForm并绑定Schema

父组件通过useForm传入验证Schema,同时设置合适的验证触发模式(mode)——默认mode为submit,仅提交时验证,改成onBlur或onChange可在用户交互时立即触发验证,解决“表单默认有效”问题:

<!-- 父组件:Form.vue -->
<template>
  <form @submit.prevent="handleSubmit(onSubmit)">
    <PasswordInput name="password" label="设置密码" />
    <PasswordInput name="confirm-password" label="确认密码" />
    <button type="submit">提交表单</button>
  </form>
</template>

<script setup>
import { useForm } from 'vee-validate';
import PasswordInput from './PasswordInput.vue';
import { formSchema } from './schemas';

const { handleSubmit } = useForm({
  validationSchema: formSchema,
  mode: 'onBlur' // 失去焦点时触发验证,可选'onChange'(输入时触发)
});

const onSubmit = (formValues) => {
  // 处理表单提交逻辑
  console.log('验证通过的表单数据:', formValues);
};
</script>

步骤3:子组件PasswordInput仅负责字段绑定

子组件无需关心验证逻辑,只需通过useField绑定父组件传递的name,处理输入和失焦事件即可:

<!-- 子组件:PasswordInput.vue -->
<template>
  <div class="form-group">
    <label>{{ label }}</label>
    <input
      type="password"
      :value="field.value"
      @input="field.handleChange($event.target.value)"
      @blur="field.handleBlur()"
      placeholder="请输入密码"
    />
    <!-- 显示字段错误信息 -->
    <span v-if="field.errorMessage" class="error-text">
      {{ field.errorMessage }}
    </span>
  </div>
</template>

<script setup>
import { useField } from 'vee-validate';

const props = defineProps({
  name: {
    type: String,
    required: true
  },
  label: {
    type: String,
    required: true
  }
});

// 绑定对应字段的状态和方法
const field = useField(props.name);
</script>

<style scoped>
.error-text {
  color: #ff4d4f;
  font-size: 0.875rem;
}
</style>

额外解决“初始表单无验证提示”

如果需要页面加载时就显示字段初始验证错误(比如空字段提示),可在父组件挂载时手动触发全量验证:

// 父组件中添加
import { onMounted } from 'vue';

const { handleSubmit, validate } = useForm({
  validationSchema: formSchema,
  mode: 'onBlur'
});

onMounted(() => {
  validate(); // 挂载时触发全量验证
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:45:35