应使用配合input事件实时过滤,并统一以“分”为单位存储整数,避免浮点运算;同时需处理光标位置防止跳转,iOS端须真机测试并降级兼容。

怎么让 不允许输入小数点和负号
原生 在 Chrome/Firefox 中默认允许输入 .、-,甚至能粘贴非数字字符(如 12.34abc),但提交时浏览器会静默截断或报错——这不是你想要的“金额控制”。关键不是靠 type="number" 自带行为,而是用 inputmode="decimal" + pattern + JS 拦截组合。
实操建议:
- HTML 层用
(仅提示软键盘,不强制校验) - 必须监听
input事件(不是change),实时过滤非法字符 - 正则替换逻辑要覆盖:开头负号、多个小数点、小数点后超两位、纯小数点
- 注意 Safari 对
inputmode支持较弱,iOS 软键盘仍可能弹出字母键
为什么直接用 parseFloat() 格式化金额会丢精度
比如用户输入 "199.99",你执行 parseFloat("199.99") * 100 得到 19998.999999999996——这是 IEEE 754 浮点数固有缺陷。金额运算绝不能走浮点路径。
实操建议:
- 所有金额统一存为「分」(整数),例如
199.99元 → 存19999(单位:分) - 显示时再除以
100并用.toFixed(2)格式化(注意.toFixed()返回字符串) - 输入框内始终显示带两位小数的字符串,不要用
Number类型做中间态 - 避免任何
+、-、*、/运算涉及小数,一律转整数再算
oninput 里怎么安全地格式化并保留光标位置
直接 el.value = formatted 会导致光标跳到末尾,用户无法在中间修改。尤其当用户想把 123.45 改成 1234.45(在 123 后插入 4),光标乱跳就等于交互失败。
实操建议:
- 先记录光标位置:
const pos = el.selectionStart - 执行格式化后,计算新值中对应原位置的偏移(比如删了 1 个字符,且删除点在光标前,则新光标位置 =
pos - 1) - 更稳妥的做法是:只允许在末尾追加、或用正则替换时固定处理逻辑(如只允许改最后两位小数),避开复杂光标计算
- 简单场景下可禁用非末尾编辑:监听
keydown,对ArrowLeft/ArrowRight/Home/End等键放行,其余方向键/删除键只在selectionEnd === value.length时响应
移动端 iOS 键盘弹不出数字+小数点怎么办
iOS Safari 对 inputmode="decimal" 支持不稳定,常回退到全键盘;而 type="number" 在部分版本会强制显示增减按钮(影响 UX),且无法限制小数位数。
实操建议:
- 组合使用:
- 配合 CSS 强制 iOS 数字键盘:
style="text-transform: uppercase;"(某些旧版有效,但不可依赖) - 终极方案:用
type="text"+inputmode="numeric",然后用 JS 把用户输入的,替换为.(适配欧洲习惯),再走统一格式化逻辑 - 务必测试真机:模拟器的键盘行为和真实 iOS 差异极大
金额输入框最难的从来不是“怎么显示小数点”,而是「用户任意编辑意图」和「数据精度刚性要求」之间的拉扯。所有正则、事件拦截、光标控制,本质都是在给用户的自由输入套一层可控外壳——这层壳一旦漏了,后端收到的就是 "12.3.4" 或 "-000.00" 这类脏数据。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











