基于Zod校验规则:根据contactNumber状态控制email字段必填性
实现邮箱与手机号的联动必填校验
根据需求,默认邮箱为必填项,当手机号字段有值时邮箱变为可选,清空手机号后邮箱恢复必填。以下是不同技术栈的实现方案:
原生JavaScript实现
通过监听手机号输入框的输入事件,动态修改邮箱的required属性,同时在表单提交时做二次校验避免绕过前端限制:
<form id="contactForm"> <div> <label for="email">邮箱:</label> <input type="email" id="email" name="email" required> </div> <div> <label for="contactNumber">手机号:</label> <input type="tel" id="contactNumber" name="contactNumber"> </div> <button type="submit">提交</button> </form> <script> const contactNumberInput = document.getElementById('contactNumber'); const emailInput = document.getElementById('email'); // 实时监听手机号输入变化 contactNumberInput.addEventListener('input', () => { const hasContact = contactNumberInput.value.trim() !== ''; emailInput.required = !hasContact; // 清除不必要的校验提示 if (hasContact && emailInput.validity.valueMissing) { emailInput.setCustomValidity(''); } }); // 表单提交时的兜底校验 document.getElementById('contactForm').addEventListener('submit', (e) => { const hasContact = contactNumberInput.value.trim() !== ''; if (!hasContact && emailInput.value.trim() === '') { e.preventDefault(); emailInput.setCustomValidity('请填写邮箱'); emailInput.reportValidity(); } else { emailInput.setCustomValidity(''); } }); </script>
Vue 3 实现
利用响应式数据动态绑定邮箱的required属性,也可结合校验库实现更规范的校验逻辑:
基础版实现
<template> <form @submit.prevent="handleSubmit"> <div> <label for="email">邮箱:</label> <input v-model="form.email" type="email" id="email" :required="!form.contactNumber.trim()" > </div> <div> <label for="contactNumber">手机号:</label> <input v-model="form.contactNumber" type="tel" id="contactNumber" > </div> <button type="submit">提交</button> </form> </template> <script setup> import { reactive } from 'vue'; const form = reactive({ email: '', contactNumber: '' }); const handleSubmit = () => { // 手动兜底校验 if (!form.contactNumber.trim() && !form.email.trim()) { alert('请填写邮箱'); return; } // 执行表单提交逻辑 console.log('提交数据:', form); }; </script>
结合VeeValidate校验库实现
<template> <Form @submit="handleSubmit"> <Field name="email" type="email" :rules="{ required: !form.contactNumber.trim() }" label="邮箱" /> <ErrorMessage name="email" class="error" /> <Field name="contactNumber" type="tel" v-model="form.contactNumber" label="手机号" /> <button type="submit">提交</button> </Form> </template> <script setup> import { Form, Field, ErrorMessage } from 'vee-validate'; import { reactive } from 'vue'; const form = reactive({ contactNumber: '' }); const handleSubmit = (values) => { console.log('提交数据:', values); }; </script>
React 函数组件实现
通过useState跟踪手机号状态,动态设置邮箱的required属性:
import { useState } from 'react'; export default function ContactForm() { const [email, setEmail] = useState(''); const [contactNumber, setContactNumber] = useState(''); const handleSubmit = (e) => { e.preventDefault(); // 兜底校验 if (!contactNumber.trim() && !email.trim()) { alert('请填写邮箱'); return; } // 执行提交逻辑 console.log('提交数据:', { email, contactNumber }); }; return ( <form onSubmit={handleSubmit}> <div> <label htmlFor="email">邮箱:</label> <input type="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} required={!contactNumber.trim()} /> </div> <div> <label htmlFor="contactNumber">手机号:</label> <input type="tel" id="contactNumber" value={contactNumber} onChange={(e) => setContactNumber(e.target.value)} /> </div> <button type="submit">提交</button> </form> ); }
内容的提问来源于stack exchange,提问作者Ankur Tyagi
相关产品推荐
相关产品推荐

