首先说明输入框中的格式限制如下:
(1)当第一位为0时,第二位只能输入小数点,且不能输入其他数字(如00)
(2)当第一位不为0时,后边不限制
(3)数据中只能输入一个小数点
(4)小数点后边保留2位
方案一:当输入后,在输入框中显示,然后检验输入内容,去掉不符合规则的数据;
优点:实现方式比较简单,通用于大多数平台(web端、移动端)
缺点:输入框中会显示一下历史不符合规则的输入的数据,然后消失
不说废话,直接上代码:
<input type="text" v-model="inputValue" @input="handleInput" />const inputValue = ref('')/*** 功能: 数据格式校验【保留2位小数】* e: input返回的值*/
const handleInput = (e: any) => {// 一定要加nextTick,否则特殊情况的更改不生效【如:000时,更改为0】nextTick(() => {let value = e.detail.value// 如果当前输入为空,直接允许清空if (!value) {inputValue.value = ''} else if (value?.charAt(0) === '0' && value.charAt(1) && value.charAt(1) !== '.') {// // 1. 当第一位为0时,只能输入小数点【第二位必须是小数点】value = '0'}value = value.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符value = value.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的value = value.match(/^\d*(\.?\d{0,2})/g)[0] || '' // 保留2位小数inputValue.value = value})
}
注意在handleInput方法中,一定要使用nextTick,否则部分赋值无效
方案二:使用自定义指令限制输入框的内容,不符合条件的,无法输入
优势:用户体验更好,使用更方便
缺点:由于uni-app对input做了一些包装,故该实现方法需要根据实际情况进行修改
(1)自定义指令
import type { Directive, App } from 'vue'/*** 输入框文本输入限制*/
export const keepTwoDecimal: Directive = {mounted(el, binding) {el.addEventListener('input',(e: any) => {try {let value = e.target.value// 1. 当第一位为0时,只能输入小数点【第二位必须是小数点】if (value.charAt(0) === '0' && value.length > 1 && value.charAt(1) !== '.') {value = '0'} else {// 当input的type不为text时,输入小数时,光标会前移,此处需要手动将光标后移(虽然此处的代码抛出了异常,但是解决了光标前移的问题)// if (e.data === '.') {// e.target.selectionStart = value.length + 1// e.target.selectionEnd = value.length + 1// }value = value.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符value = value.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的value = value.match(/^\d*(\.?\d{0,2})/g)![0] || '' // 保留2位小数}e.target.value = value} catch (e) {throw new Error('输入时发生异常!')}},true,) // 由于uni-app中渲染原生的input时,增加了dom解构,此处无法直接获取input标签的输入事件,故设置为true,添加向下捕获事件},
}export function setupInputDirective(app: App) {app.directive('input-decimal', keepTwoDecimal)
}
(2)使用方法
<input class="input" type="text" v-input-decimal inputmode="numeric" v-model="inputValue" placeholder="请输入" />
注意:
(1)在自定义指令中,addEventListener的监听方法中要添加向下的捕获事件(因为uni-app将input包括了多层),即在其后边多传一个参数true,表示向下捕获.
(2)在使用时,直接使用“v-input-decimal”指令即可;
(3)如果在输入时,想直接调起数字键盘,需要添加inputmode="numeric"属性;
(4)如果type不等于text时,输入小数点时,光标会前移,为了解决此问题,需要在自定义指令中添加额外的判断(自定义的代码中已添加注释说明)
以上思路为自己在工作中的经验总结,如有问题,欢迎大家留言讨论!
本问为作者原创,如有需要,请注明出处,尊重原创,十分感谢!