uni-data-select 不适合做数字选择器,应改用 uni-number-box 或手写 input+按钮组实现;后者需处理格式化显示、输入校验、键盘适配及跨平台兼容性问题。

uni-data-select 不适合做数字选择器,别硬套
直接用 uni-data-select 实现「数字选择器」是走错路。它本质是枚举型下拉菜单,数据源必须是固定 value/text 对象数组,不支持动态范围、步进、格式化显示(如带单位、千分位、小数精度控制),也不响应键盘输入或滚轮操作。
你真正需要的是一个「数值输入控件」,不是「选项选择控件」。强行给 localdata 塞 1–100 的对象列表,既卡顿又难维护,还无法处理用户手动输入的数字。
用 uni-number-box 是最省事的起点
uni-number-box 是 uni-ui 官方提供的数字输入框组件,轻量、跨端、支持基础交互。它不渲染下拉菜单,但提供增减按钮 + 手动输入双模式,符合多数业务场景。
- 默认支持整数,设
:min="0" :max="100" :step="1"即可限制范围 - 要支持小数?加
:decimal-length="2"控制小数位数,同时:step="0.01" - 显示带单位?用插槽:
<template #prepend>¥</template>或<template #append>元</template> - 注意:nvue 下需确保
manifest.json中"nvueStyleCompiler": "uni-app"已配置,否则样式错乱
需要完全自定义 UI?封装一个 input + 按钮组
当设计稿要求特殊按钮形状、动画、禁用态样式,或需集成到弹层/侧滑面板中时,uni-number-box 的样式覆盖成本会超过重写。这时推荐手写结构:
核心是用原生 <input type="number"> 绑定 v-model.number,再配两个按钮触发增减逻辑:
<view class="num-input">
<button @click="decrease" :disabled="modelValue <= min">−</button>
<input
type="number"
:value="modelValue"
@input="onInput"
@blur="onBlur"
:min="min"
:max="max"
/>
<button @click="increase" :disabled="modelValue >= max">+</button>
</view>
-
@input里用parseInt($event.detail.value)或parseFloat转类型,避免字符串拼接 -
@blur时做边界校验和四舍五入(比如金额输 19.999 → 自动转成 20.00) - 移动端需加
inputmode="decimal"(iOS)或pattern="[0-9]*"(Android)唤起数字键盘 - 别忘了在
props里暴露min、max、step、format(函数,用于显示前格式化)等参数
格式化显示和输入校验最容易被忽略
数字选择器的「格式」不是纯展示问题,它直接影响用户输入体验和后端接收逻辑。比如价格输「10000」显示为「10,000.00」,但提交时仍要传原始数字,不能传字符串。
- 显示用
toLocaleString():modelValue?.toLocaleString('zh-CN', { minimumFractionDigits: 2 }) - 但输入时必须监听原始值,不能对
input的value直接格式化——否则光标会跳、输入中断 - 建议拆成两个字段:
rawValue(绑定 input,始终为 number)和displayValue(computed,仅用于显示) - 用户粘贴「¥12,345.67」这种带符号和逗号的内容?用正则
value.replace(/[^\d.-]/g, '')清洗后再 parse
跨平台时,iOS 的 input[type=number] 对小数点支持不稳定,真要高保真,得在 nvue 下用 uni-popup + 自定义滚轮选择器,但开发成本陡增——先确认是否真有必要。


















