uni-app 中 type="number" 无法实现纯数字键盘,因 iOS/Android 实现不一且微信小程序不支持;需用 view + bindtap 自定义键盘,隐藏原生 input,手动控制输入值与聚焦,并注意 iOS 微信下 focus/blur 引发的闪退问题。

uni-app 里为什么不能直接用 input 的 type="number" 弹出纯数字键盘?
因为 iOS 和 Android 对 type="number" 的实现不一致:iOS 会弹出带小数点和负号的键盘,Android 可能直接弹出全键盘或拼音键盘;更关键的是,微信小程序环境压根不支持该 type 的语义化键盘切换,只走系统默认软键盘。所以靠原生 input 搞不定「只有 0–9 + 删除键」的定制需求。
怎么用 view + bindtap 实现轻量级数字键盘组件?
核心思路是:隐藏原生 input(设 opacity: 0 或 position: absolute; left: -999px),用自定义 view 模拟按键,点击时通过 this.$refs.inputRef.value 或 v-model 绑定的数据手动拼接/截断字符串。
- 键盘按钮用
view布局,每格绑定@tap="onKeyTap",传入keyVal(如'1'、'del') - 输入框必须设
focus属性为true并用uni.focus()触发聚焦(否则 iOS 不响应blur后再聚焦的逻辑) - 删除键要兼容空值:若当前值为空,不执行
.slice(0, -1),避免报错 - 示例片段:
<input v-model="inputValue" :focus="isFocused" @focus="onInputFocus" /> <view class="keyboard"> <view v-for="k in keys" @tap="onKeyTap(k)">{{ k }}</view> </view>
如何让键盘在 iOS 微信小程序里不闪退、不卡死?
这是最常翻车的点:iOS 微信下频繁操作 input 的 focus 和 blur 容易触发渲染异常,表现为键盘闪一下就收、输入框失焦后无法再聚焦。
- 不要在每次按键后调
blur+focus—— 只在首次打开键盘时调一次focus() - 用
input的confirm-type="done"配合右上角「完成」按钮收起键盘,而非监听blur做清理 - 避免在
onKeyTap中直接修改v-model后立刻调focus(),改用this.$nextTick(() => uni.focus())确保 DOM 更新完成 - 如果用了
uni.createSelectorQuery()获取input节点,注意 iOS 下必须等页面onReady后才能查到节点,否则返回 null
要不要封装成独立 custom-keyboard 组件?
要,但别过度设计。真正需要复用的只有三件事:按键布局、输入逻辑、收起时机。其余如样式、宽度、是否带「确认」键,都该由父组件传 props 控制。
- 必传
props:value(双向绑定值)、disabled(禁用状态)、showConfirm(是否显示确认键) - 事件只暴露
@confirm和@change,不暴露@keytap这种底层细节 - 键盘高度建议固定为
280rpx,适配主流屏宽;用position: fixed; bottom: 0+z-index: 999,避免被scroll-view截断 - 注意:uni-app 的
scoped样式对子组件无效,键盘内部按钮的 active 态要用:active伪类 +touchstart降级兼容


















