如何使用Chakra UI实现输入框仅接受数字输入?
解决手机号输入框允许字母输入及提交的问题
为什么type="tel"不生效?
type="tel"的核心作用是在移动设备唤起数字键盘,但不会强制限制用户输入非数字字符,不同浏览器对该类型的输入约束没有统一标准,因此会出现可输入字母的情况。
解决方案
从实时输入过滤、浏览器原生验证、表单库校验三个维度入手,结合你的Chakra UI代码,具体实现如下:
1. 实时过滤非数字输入
在输入变更时直接过滤掉非数字字符,确保输入框内始终只有数字:
const handlePhoneChange = (e) => { // 移除所有非数字字符 const numericValue = e.target.value.replace(/\D/g, ''); // 调用原表单变更处理函数 handleChange({ ...e, target: { ...e.target, value: numericValue } }); };
将Input组件的onChange替换为上述自定义函数:
<Input type='tel' name='number' h={10} borderColor='#24392E' errorBorderColor='#ef5350' placeholder='Phone number' value={values.number} onChange={handlePhoneChange} // 替换为自定义处理函数 onBlur={onBlur} _hover={{ borderColor: '#7fa87f', }} />
2. 添加原生pattern验证
给Input添加pattern属性指定手机号正则规则(以中国大陆11位手机号为例),浏览器会在提交时自动校验格式:
<Input type='tel' name='number' pattern="^1[3-9]\d{9}$" // 中国大陆手机号正则 title="请输入有效的11位手机号" // 验证失败时的提示文本 // 其他属性保持不变 />
3. 表单库层面加强校验
如果使用React Hook Form这类表单库,可通过校验规则进一步确保手机号格式合法:
// 示例:用yup定义校验规则 import * as yup from "yup"; const phoneSchema = yup.object().shape({ number: yup.string() .matches(/^1[3-9]\d{9}$/, "请输入有效的11位手机号") .required("手机号不能为空"), });
将校验规则绑定到表单后,提交前会自动触发格式校验。
最终修改后的完整代码示例
import { FormControl, FormLabel, Input, FormErrorMessage } from "@chakra-ui/react"; import { useForm } from "react-hook-form"; import * as yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; // 定义表单校验规则 const schema = yup.object().shape({ number: yup.string() .matches(/^1[3-9]\d{9}$/, "请输入有效的11位手机号") .required("手机号不能为空"), }); const PhoneForm = () => { const { register, handleSubmit, formState: { errors, touched } } = useForm({ resolver: yupResolver(schema), }); // 自定义手机号输入处理函数 const handlePhoneChange = (e) => { const numericValue = e.target.value.replace(/\D/g, ''); register('number').onChange({ ...e, target: { ...e.target, value: numericValue } }); }; const onSubmit = (data) => { console.log("提交的手机号:", data.number); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <FormControl isRequired isInvalid={touched.number && errors.number} mb={2} width='100%' > <FormLabel fontSize='lg' fontFamily='Proxima Nova' fontWeight='500'> Phone number </FormLabel> <Input type='tel' name='number' h={10} borderColor='#24392E' errorBorderColor='#ef5350' placeholder='Phone number' {...register('number')} onChange={handlePhoneChange} _hover={{ borderColor: '#7fa87f', }} /> <FormErrorMessage> {errors.number?.message || "Required"} </FormErrorMessage> </FormControl> <button type="submit">提交</button> </form> ); }; export default PhoneForm;
内容的提问来源于stack exchange,提问作者maxheezy's
相关产品推荐
相关产品推荐

