如何通过onInput实现输入框仅允许输入带小数的正数字
支持小数的非负货币输入实现方案
原有方案使用Math.abs做值转换的逻辑会自动截断小数,核心原因是数值转换过程会把输入过程中的半完成状态(比如刚输入小数点还没填后续数字的状态)做整数化处理,打断正常输入流程。可以直接用下面的onInput逻辑替换原有代码,同时兼容非负校验、小数输入,适配货币类字段场景:
onInput={(e) => { // 第一步:过滤所有非数字、非小数点的字符(自动拦截负号、字母、特殊符号) let inputVal = e.target.value.replace(/[^\d.]/g, ''); // 第二步:处理重复输入的小数点,仅保留第一个有效小数点 inputVal = inputVal.replace(/\.{2,}/g, '.'); inputVal = inputVal.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); // 第三步(货币场景可选):限制最多保留2位小数,不需要可直接删除该行 inputVal = inputVal.match(/^\d*(\.?\d{0,2})/g)[0] || ''; e.target.value = inputVal; }}
补充说明
- 单独给input加
min={0}属性无法拦截用户手动输入的负数:该属性仅在原生表单提交、调用原生checkValidity()校验方法时生效,输入过程中、手动赋值场景都不会自动拦截非法值,必须配合输入时的字符过滤逻辑使用。 - 上述逻辑不会打断用户正常输入流程:比如输入到
99.还未填写小数位的中间状态会被正常保留,不会被强制转成整数。如果不需要限制小数位数,删除第三步的代码即可支持任意位小数的非负数字输入。 - 建议在表单提交前加一层兜底校验:判断最终转换为数字的输入值
Number(inputVal) >= 0,覆盖极端场景下的异常值提交问题。
内容的提问来源于stack exchange,提问作者Faziki
相关产品推荐
相关产品推荐

