真正可用的方案是用6个独立input,绑定v-model到长度为6的数组,type设为tel或number,配合ref数组控制光标移动、退格跳转、粘贴分位填充,并用$nextTick和setTimeout兜底聚焦。

uni-app里怎么用input实现六位数字验证码输入框
直接用一个input加maxlength="6"不行——用户无法逐位聚焦、删除时逻辑混乱、粘贴体验差。真正可用的方案是用6个独立的input,配合focus/blur和input事件手动控制光标移动。
关键点在于:每个input只允许数字,长度为1;输入后自动跳到下一个;退格键时反向聚焦前一个;粘贴时按顺序填满可编辑位。
- 必须给每个
input设type="number"或type="tel"(type="text"配pattern="[0-9]"在部分安卓机无效) - 绑定
v-model到长度为6的数组,如code: ['', '', '', '', '', ''] - 用
ref数组管理6个input实例,便于focus()调用 - 禁用长按复制/粘贴的默认菜单可加
user-select: none,但粘贴功能需单独处理(监听@paste)
如何处理粘贴六位验证码
用户从微信/短信粘贴验证码时,原生input事件不触发,必须显式监听@paste。且不能直接赋值整个字符串——要按位写入当前焦点位置起的连续空位。
示例逻辑:onPaste(e)中e.clipboardData.getData('text')取值,过滤非数字,截取最多6位,再从当前index开始依次填入code数组,填完即focus到最后一位(或自动提交)。
- 注意:
paste事件里不能直接focus()下一个input,需用$nextTick延后执行 - 如果粘贴内容少于剩余空位,只填对应数量,不重置已填位
- iOS Safari 对
clipboardData支持不稳定,可降级为监听input后检查长度是否突增
为什么type="number"在某些安卓机上会出问题
部分安卓 WebView(如旧版QQ浏览器、部分厂商定制系统)对type="number"的input事件响应异常:输入后value为空字符串、compositionstart干扰导致重复触发、退格键无法触发input事件。
更稳的组合是:type="tel" + inputmode="numeric" + pattern="[0-9]*"。其中inputmode是关键,它告诉软键盘弹出数字盘,且不影响事件流。
-
type="tel"不会触发表单验证,也不会自动添加国家码 -
pattern仅作提示,实际仍需在@input中用val.replace(/\D/g, '')清洗 - 避免用
type="digit"——非标准属性,uni-app H5 和小程序都不识别
真机调试时容易忽略的聚焦行为差异
模拟器里focus()基本都成功,但真机(尤其iOS)存在聚焦失败却不报错的情况:比如上一个input还在compositionend过程中,就调focus()下一个,结果光标没动。
稳妥做法是:每次focus()前先blur()当前项,并用$nextTick包裹;对iOS额外加setTimeout(..., 100)兜底;同时监听focus事件确认是否真正获得焦点,失败则重试一次。
- 不要依赖
document.activeElement判断——小程序环境不支持 - uni-app 的
ref在v-for中必须用数组,不能用对象键名,否则ref无法正确映射到实例 - 微信小程序真机下,
focus可能被系统键盘遮挡,需配合scroll-into-view滚动到可视区
实际跑通的关键不在布局多漂亮,而在每位输入、删除、粘贴、失焦这四件事的边界是否都覆盖到了。尤其是粘贴和iOS聚焦,不连真机测三遍很难发现漏掉的case。











