React金额输入组件开发求助:自动格式化无需手动输入小数点
React金额输入组件(基于ShadCN实现)
核心思路
- 用整数存储金额(以分为单位),彻底避开浮点精度问题
- 仅允许输入数字键,输入的数字自动追加到数值末尾(等价于原数×10加新数字)
- 退格时将数值÷10取整,反向还原格式
- 实时将整数金额转换为带千分位、两位小数的字符串展示
完整代码实现
import { useState, useRef, useEffect } from 'react'; import { Input } from '@/components/ui/input'; const MoneyInput = () => { // 原始金额(单位:分),初始值0对应显示0.00 const [rawAmount, setRawAmount] = useState<number>(0); // 输入框引用,用于控制光标位置 const inputRef = useRef<HTMLInputElement>(null); // 将分格式化为带千分位的金额字符串 const formatAmount = (cents: number): string => { // 转换为元并保留两位小数 const dollars = (cents / 100).toFixed(2); // 给整数部分添加千分位分隔符 return dollars.replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; // 处理键盘输入事件 const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { // 仅允许数字键和退格键 const allowedKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Backspace']; if (!allowedKeys.includes(e.key)) { e.preventDefault(); return; } // 处理数字输入 if (e.key >= '0' && e.key <= '9') { e.preventDefault(); // 追加数字:原金额×10 + 新数字,限制最大值避免溢出 const newRawAmount = rawAmount * 10 + parseInt(e.key, 10); if (newRawAmount <= 999999999) { setRawAmount(newRawAmount); } } // 处理退格删除 if (e.key === 'Backspace') { e.preventDefault(); // 反向还原:原金额÷10取整 setRawAmount(Math.floor(rawAmount / 10)); } }; // 处理粘贴等非键盘输入场景 const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { // 提取输入内容中的纯数字 const pureDigits = e.target.value.replace(/\D/g, ''); setRawAmount(pureDigits ? parseInt(pureDigits, 10) : 0); }; // 更新金额后,自动将光标移到输入框末尾,保证输入流畅性 useEffect(() => { if (inputRef.current) { inputRef.current.focus(); inputRef.current.setSelectionRange( inputRef.current.value.length, inputRef.current.value.length ); } }, [rawAmount]); return ( <Input ref={inputRef} type="text" value={formatAmount(rawAmount)} placeholder="0.00" onKeyDown={handleKeyDown} onChange={handleChange} /> ); }; export default MoneyInput;
关键细节说明
- 整数存储:以分为单位存储金额,彻底避免
0.1 + 0.2 = 0.30000000000000004这类浮点精度问题 - 键盘拦截:直接拦截非数字、非退格的按键,避免无效字符干扰格式
- 格式化逻辑:通过正则表达式自动给整数部分添加千分位分隔符,完全匹配需求格式
- 光标控制:每次金额更新后自动将光标移到末尾,输入时不会出现光标跳位问题
- 兼容粘贴:提取粘贴内容中的纯数字更新金额,容错性更强
测试效果
输入数字时:
- 输入
1→ 显示0.01 - 输入
2→ 显示0.12 - 输入
3→ 显示1.23 - 输入
4→ 显示12.34 - 输入
5→ 显示123.45 - 输入
6→ 显示1,234.56
删除时:
- 按退格 →
1,234.56→123.45 - 再按退格 →
123.45→12.34 - 持续按退格会依次还原至
0.00
内容的提问来源于stack exchange,提问作者everspader
相关产品推荐
相关产品推荐

