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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:23:13