当前位置:   article > 正文

Vue input表单number类型保留两位小数,并防止输入多个小数点解决方法,自定义NumberInput组件_vue number 小数

vue number 小数

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

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

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

  1. vue在申明表单model的时候必须是整形,要不然一堆红报错。
  2. maxlength属性不生效了,无法限制表单输入长度。
  3. 可以多次输入小数点,其实这个model已经变成空值了,这个是最坑的
  4. 无法保留指定小数位数。
  5. 无法限制最大值,最小值。

思路一:用原生oninput函数实现输入正则替换,自定义函数替换字符。(会破坏vue统一性,不推荐

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

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

<input class="amount-input" size="10" maxlength="6" type="number" placeholder="请输入金额" v-model.number="formData.amount">
  1. watch:{
  2. 'formData.amount':function (newVal,oldVal) {
  3. // 解决数字键盘可以输入输入多个小数点问题
  4. if(newVal==='' && oldVal.toString().indexOf('.')>0){
  5. this.formData.amount = oldVal;
  6. return ;
  7. }
  8. // 保留两位小数
  9. if(newVal){
  10. newVal = newVal.toString();
  11. var pointIndex = newVal.indexOf('.');
  12. if(pointIndex>0 && (newVal.length - pointIndex)>3){
  13. this.formData.amount = oldVal;
  14. return ;
  15. }
  16. }
  17. // 最大值
  18. if(newVal>999999){
  19. this.formData.amount = oldVal;
  20. return ;
  21. }
  22. }
  23. }

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

 

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

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

  1. <template>
  2. <input class="my-number-input" type="number" :placeholder="placeholder" v-model.number="inputModel">
  3. </template>
  4. <script type="text/ecmascript-6">
  5. export default {
  6. components: {},
  7. props: {
  8. point:{
  9. default: 0
  10. },
  11. max:Number,
  12. placeholder:String,
  13. value: {
  14. default: null
  15. },
  16. },
  17. computed:{
  18. inputModel: {
  19. get:function() {
  20. // 父组件==>子组件 发消息
  21. return this.value;
  22. },
  23. set:function (value) {
  24. // 子组件==>父组件 发消息
  25. let val = this.$el.value;
  26. let len = val.length;
  27. console.log(val);
  28. // 解决首位直接输入 '0开头的数字'问题
  29. if(len==2 && val.charAt(0)==0 && val.charAt(1)!='.'){
  30. this.$el.value = val.charAt(1);
  31. this.setParentModeVal(this.$el.value);
  32. return;
  33. }
  34. // 解决数字键盘可以输入输入多个小数点问题
  35. if(Math.abs(this.value) > 0 && val==='' && value ===''){
  36. if(this.keyDownDel){
  37. this.$el.value = '';// 正常删除
  38. console.log('---正常删除---'+this.value);
  39. }else {
  40. this.$el.value = this.value;// 多次输入小数点时
  41. console.log('---多次输入小数点---'+this.value);
  42. }
  43. this.setParentModeVal(this.$el.value);
  44. return ;
  45. }
  46. // 解决开始就输入点问题
  47. if(this.value === '' && val === '' && value === ''){
  48. console.log('---22aa---'+this.value);
  49. this.$el.value = '';
  50. this.setParentModeVal('');
  51. return ;
  52. }
  53. // 解决保留两位小数问题
  54. if(val){
  55. let pointIndex = val.indexOf('.');
  56. if(this.point==0 && len==2 && val.charAt(pointIndex)=='.'){
  57. console.log('只能输入整数');
  58. this.$el.value = val.substr(0,pointIndex);
  59. this.setParentModeVal(this.$el.value);
  60. return ;
  61. }
  62. if(pointIndex>0 && (len - pointIndex)>(this.point+1)){
  63. console.log('只能输入'+this.point+'位小数');
  64. this.$el.value = val.substr(0,pointIndex + this.point +1);
  65. this.setParentModeVal(this.$el.value);
  66. return ;
  67. }
  68. }
  69. // 解决输入最大值问题
  70. if(this.max>0 && val>this.max){
  71. console.log('---4---')
  72. this.$el.value = val.substr(0,len-1);
  73. this.setParentModeVal(this.$el.value);
  74. return;
  75. }
  76. this.setParentModeVal(val);
  77. return;
  78. }
  79. }
  80. },
  81. data() {
  82. return {
  83. keyDownDel:false,// 判断键盘输入值
  84. }
  85. },
  86. mounted() {
  87. // 判断键盘是否是删除动作
  88. var that = this;
  89. window.document.onkeydown = function(event){
  90. let e = event || window.event || arguments.callee.caller.arguments[0];
  91. if(e.keyCode==8||e.keyCode==46){
  92. that.keyDownDel = true;
  93. }else {
  94. that.keyDownDel = false;
  95. }
  96. };
  97. },
  98. methods: {
  99. setParentModeVal(value){
  100. this.value = value;
  101. this.$emit('input', value);
  102. }
  103. },
  104. }
  105. </script>
  106. <style lang="stylus" rel="stylesheet/stylus">
  107. .my-number-input{
  108. //user-select: auto;
  109. //border: 1px solid #ccc; // 去除默认未选中状态边框
  110. //outline: none; // 去除默认选中状态边框
  111. //background-color: rgba(0, 0, 0, 0);// 透明背景
  112. //padding: 2px;
  113. }
  114. </style>

组件使用:

1. 导入:

import MyNumberInput from '@/components/Plugin/Form/MyNumberInput';

2. 注册:

  1. export default {
  2. components: {
  3. MyNumberInput //注册
  4. },
  5. data() {
  6. },
  7. mounted() {
  8. },
  9. }

3. 视图:

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

属性说明:

  1. point 保留小数位数 ,默认0
  2. max 最大数,默认无限
  3. placeholder 输入提示 默认空
  4. v-model 绑定数据对象

解决问题:

  1. 解决首位直接输入 '0开头的数字'问题
  2. 解决数字键盘输入多个小数点问题
  3. 解决开始就输入点问题
  4. 解决保留两位小数问题
  5. 解决输入最大值问题
  6. 解决了默认弹出数字键盘问题
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/549545
推荐阅读
相关标签
  

闽ICP备14008679号