uni-app + vue3实现input输入框保留2位小数的2种方案

本文介绍了两种处理输入框数值格式的方法,方案一是使用`handleInput`函数实时校验,显示并清理不符合规则的数据;方案二是通过Vue自定义指令`input-decimal`提供更好的用户体验。特别关注了uni-app环境中的实现细节。
摘要由CSDN通过智能技术生成

首先说明输入框中的格式限制如下:

(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 if(value.length === 1 && value.charAt(0) === '.') {
            // 如果第一位输入的是小数点,则直接置空
            value = ''
          } 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时,输入小数点时,光标会前移,为了解决此问题,需要在自定义指令中添加额外的判断(自定义的代码中已添加注释说明)

以上思路为自己在工作中的经验总结,如有问题,欢迎大家留言讨论!

本问为作者原创,如有需要,请注明出处,尊重原创,十分感谢!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值