最可靠方案是 edit: "text" + input 事件实时清洗:监听 input 事件用 /[^\d]/g 清除非数字字符,空值或全零串转为 '0',主动赋值 this.value,并用事件委托绑定防重载失效。

edit: "text" + input事件实时清洗最可靠
Layui 的 edit: "number" 只改 type 属性,不拦截粘贴、拖入、双小数点、负号等非法输入,实际等于没锁。真正能控住内容的,是监听 input 事件做字符串清洗——它在每次输入、粘贴、剪切后都触发,比 keydown 更全面。
常见错误现象:edit: "number" 下用户粘贴 "-123.45abc" 或拖一个文件进输入框,值直接变成乱码;手动输 123..4 也能过;blur 后才校验,但脏数据已经进 DOM 了。
- 用正则
/[^\d]/g清除非数字字符(不含小数点,因要纯整数) - 对空值、全零串(如
"000")做parseInt()转换,避免前导零残留 - 必须用事件委托绑定,防止表格重载后失效:
layui.$(document).on('input', '.layui-table-edit', ...) - 清洗后要主动赋值回
this.value,否则界面不更新
为什么不能只靠 lay-verify="number"
lay-verify="number" 是表单提交时的校验钩子,跟单元格编辑完全无关——表格的 edit 模式不走 layui 表单验证流程,lay-verify 在这里压根不执行。
使用场景很明确:后台管理中“订单数量”“库存件数”这类字段,业务规则要求必须是正整数,前端放任用户输 "1.5" 或 "abc",后端收到后要么报错,要么静默转成 0,排查成本远高于前端拦住。
- 即使你在列配置里写
edit: "text", templet: '',Layui 也不会自动挂验证逻辑 -
lay-verify只对form.render()管理下的静态表单生效,动态插入的编辑框不在其管辖范围 - 想用验证提示,得自己调
layer.msg(),且必须在input或blur里手动触发
templet + event 方案适合需要 min/max 或强交互的场景
如果字段有硬性约束,比如“最大库存不能超 9999”,或需配合上下箭头微调,edit 字段就彻底不够用了,必须上 templet 自定义 input 并绑定 event 手动接管。
注意:templet 和 edit 互斥,一旦用了 templet,Layui 就不再自动生成编辑框,所有焦点、取值、回填都得你写代码处理。
- 列配置中去掉
edit,加templet和event,例如:{ field: 'stock', templet: '', event: 'edit_stock' } - 监听
table.on('tool(table-filter)', ...),在obj.event === 'edit_stock'时聚焦 input 并补全逻辑 - input 失焦或回车时,用
parseFloat()转值,再判断是否在范围内,超限就重置并提示 - 别忘了给 input 加
inputmode="numeric",iOS 键盘才默认弹数字键盘
容易忽略的兼容性细节
很多方案在 Chrome 里跑得顺,一到 iOS Safari 就出问题:type="number" 触发小数点异常、长按粘贴菜单消失、软键盘不弹出数字键——这些不是 bug,是浏览器策略差异。
关键点不在“能不能输”,而在“用户看到的反馈是否一致”。比如用户粘贴 "12a3",Chrome 下可能显示 "123",Safari 却卡在 "12" 不动,体验断层。
- 务必在
input事件里做清洗,不要依赖change或blur,后者太晚 - 正则用
/[^\d]/g,别用/\D/g(某些旧版 Safari 对 \D 支持不稳定) - 对空输入或全零串,显式设
this.value = '0',避免 iOS 下清空后留空白格 - 如果项目要支持 IE11,
type="number"直接放弃,全程用edit: "text"+input清洗











