VUE 表单input保留n位小数【1/2】(input=“number“类型,防止输入多个小数点,自定义NumberInput组件)

背景:Vue开发移动端应用时,难免用到表单输入,比如金额。

需求:这时就需要吊起移动端数字键盘,input的type就必须设置成number,当然tel类型也可以,但是无法输入小数点。当然如果精力允许,你也可以自定义数字键盘是最好的,网上也有很多Vue数字键盘组件。

踩坑:一但用了input[type=number]类型有很多的坑

vue在申明表单model的时候必须是整形,要不然一堆红报错。
maxlength属性不生效了,无法限制表单输入长度。
可以多次输入小数点,其实这个model已经变成空值了,这个是最坑的。
无法保留指定小数位数。
无法限制最大值,最小值。
思路一:用原生oninput函数实现输入正则替换,自定义函数替换字符。(会破坏vue统一性,不推荐)

思路二:用vue的@nput函数实现输入正则替换,自定义函数替换字符。(实现麻烦,不推荐)

思路三:用vue的变量监听函数。(输入某些值情况下不会被触发,不推荐)

<input class="amount-input" size="10" maxlength="6" type="number" placeholder="请输入金额" v-model.number="formData.amount">

watch:{
    'formData.amount':function (newVal,oldVal) {
      // 解决数字键盘可以输入输入多个小数点问题
      if(newVal==='' && oldVal.toString().indexOf('.')>0){
        this.formData.amount = oldVal;
        return ;
      }
      // 保留两位小数
      if(newVal){
        newVal = newVal.toString();
        var pointIndex =  newVal.indexOf('.');
        if(pointIndex>0 && (newVal.length - pointIndex)>3){
          this.formData.amount = oldVal;
          return ;
        }
      }
      // 最大值
      if(newVal>999999){
        this.formData.amount = oldVal;
        return ;
      }
    }
  }


上面的方法解决了,可以多次输入小数点问题,和保留小数位数,还有限制大小都可以在这里实现,因为监听函数可以获取到历史输入值,很方便还原,不过在输入点的时候不会被触发,所以不是很理想。

思路四:用vue的computed函数,实现父组件和子组件双向通信。(为了方便大家使用我单独封装了一个插件MyNumberInput.vue,推荐,推荐,推荐,完美)

path:@/components/Plugin/Form/MyNumberInput.vue

<template>
  <input class="my-number-input"  type="number" :placeholder="placeholder" v-model.number="inputModel">
</template>
<script type="text/ecmascript-6">
  export default {
    components: {},
    props: {
      point:{
        default: 0
      },
      max:Number,
      placeholder:String,
      value: {
        default: null
      },
    },
    computed:{
      inputModel: {
        get:function() {
          // 父组件==>子组件 发消息
          return this.value;
        },
        set:function (value) {
 
          // 子组件==>父组件 发消息
          let val = this.$el.value;
          let len = val.length;
          console.log(val);
 
          // 解决首位直接输入 '0开头的数字'问题
          if(len==2 && val.charAt(0)==0 && val.charAt(1)!='.'){
            this.$el.value = val.charAt(1);
            this.setParentModeVal(this.$el.value);
            return;
          }
 
          // 解决数字键盘可以输入输入多个小数点问题
          if(Math.abs(this.value) > 0 && val==='' && value ===''){
            if(this.keyDownDel){
              this.$el.value = '';// 正常删除
              console.log('---正常删除---'+this.value);
            }else {
              this.$el.value = this.value;// 多次输入小数点时
              console.log('---多次输入小数点---'+this.value);
            }
            this.setParentModeVal(this.$el.value);
            return ;
          }
 
          // 解决开始就输入点问题
          if(this.value === '' && val === '' && value === ''){
            console.log('---22aa---'+this.value);
            this.$el.value = '';
            this.setParentModeVal('');
            return ;
          }
 
          // 解决保留两位小数问题
          if(val){
            let pointIndex =  val.indexOf('.');
            if(this.point==0 && len==2 && val.charAt(pointIndex)=='.'){
              console.log('只能输入整数');
              this.$el.value = val.substr(0,pointIndex);
              this.setParentModeVal(this.$el.value);
              return ;
            }
            if(pointIndex>0 && (len - pointIndex)>(this.point+1)){
              console.log('只能输入'+this.point+'位小数');
              this.$el.value = val.substr(0,pointIndex + this.point +1);
              this.setParentModeVal(this.$el.value);
              return ;
            }
          }
 
          // 解决输入最大值问题
          if(this.max>0 && val>this.max){
            console.log('---4---')
            this.$el.value = val.substr(0,len-1);
            this.setParentModeVal(this.$el.value);
            return;
          }
 
          this.setParentModeVal(val);
          return;
        }
      }
    },
    data() {
      return {
        keyDownDel:false,// 判断键盘输入值
      }
    },
    mounted() {
      // 判断键盘是否是删除动作
      var that = this;
      window.document.onkeydown = function(event){
        let e = event || window.event || arguments.callee.caller.arguments[0];
        if(e.keyCode==8||e.keyCode==46){
          that.keyDownDel = true;
        }else {
          that.keyDownDel = false;
        }
 
      };
    },
    methods: {
        setParentModeVal(value){
          this.value = value;
          this.$emit('input', value);
        }
    },
  }
</script>
 
<style  lang="stylus" rel="stylesheet/stylus">
  .my-number-input{
    //user-select: auto;
    //border: 1px solid #ccc;  // 去除默认未选中状态边框
    //outline: none; // 去除默认选中状态边框
    //background-color: rgba(0, 0, 0, 0);// 透明背景
    //padding: 2px;
  }
</style>


组件使用:

1. 导入:

import MyNumberInput from '@/components/Plugin/Form/MyNumberInput';
2. 注册:

export default {
    components: {
       MyNumberInput //注册 
    },
    data() {
    },
    mounted() {
    },
}
3. 视图:

<MyNumberInput :point="2" :max="99999" placeholder="请输入金额" v-model.number="formData.amount"></MyNumberInput>
属性说明:

point 保留小数位数 ,默认0
max 最大数,默认无限
placeholder 输入提示 默认空
v-model 绑定数据对象
解决问题:

解决首位直接输入 '0开头的数字'问题
解决数字键盘输入多个小数点问题
解决开始就输入点问题
解决保留两位小数问题
解决输入最大值问题
解决了默认弹出数字键盘问题


————————————————
原文链接:https://blog.csdn.net/veloi/article/details/89022499

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值