Forráskód Böngészése

Merge pull request #137 from baiyaaaaa/next

fix input-number
baiyaaaaa 9 éve
szülő
commit
f6dd3cf7bc
3 módosított fájl, 85 hozzáadás és 34 törlés
  1. 1 0
      CHANGELOG.md
  2. 23 13
      examples/docs/input-number.md
  3. 61 21
      packages/input-number/src/input-number.vue

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@
 - 修复 TimePicker 的 `picker-options` 属性
 - 修复一些组件图标丢失的问题
 - 修复远程搜索的 Select 在 Form 中的显示问题
+- 修复 input-number 输入小数和非数字值时的问题
 
 ### 1.0.0-rc.1
 

+ 23 - 13
examples/docs/input-number.md

@@ -6,6 +6,11 @@
         num2: 1,
         num3: 5
       }
+    },
+    methods: {
+      handleChange(value) {
+        console.log(value);
+      }
     }
   };
 </script>
@@ -16,20 +21,19 @@
     }
   }
 </style>
-## Input Number 数字输入框
-通过鼠标或键盘输入字符
 
-### 基础使用
+## Input Number 数字输入框
 
-需要标准的数字值时可以用到 Input Number 组件,你提供了数值输入提供了范围控制和递增递减的步数控制。
+仅允许输入标准的数字值,可定义范围
 
-值得一提的是,你可以不用通过连续点击增减,可以直接输入数字或者长按按钮进行数字的改变。
+### 基础用法
 
+需要标准的数字值时可以用到 Input Number 组件,它提供了数值输入,范围控制和递增递减的步数控制等功能。
 
 :::demo 要使用它,只需要在`el-input-number`元素中使用`v-model`绑定变量即可,变量的初始值即为默认值。
 ```html
 <template>
-  <el-input-number v-model="num1"></el-input-number>
+  <el-input-number v-model="num1" @change="handleChange"></el-input-number>
 </template>
 <script>
   export default {
@@ -53,9 +57,9 @@
 ```
 :::
 
-### 步
+### 步
 
-让组件按照步长来增减。
+允许定义递增递减的步数控制
 
 :::demo 设置`step`属性可以控制步长,接受一个`Number`。
 
@@ -80,8 +84,14 @@
 ### Attributes
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |
 |----------|-------------- |----------|--------------------------------  |-------- |
-| min      | 设置计数器允许的最小值 | number |   | 0 |
-| max      | 设置计数器允许的最大值 | number |   | Infinity |
-| step     | 计数器步长           | number   |      | 1 |
-| size     | 计数器尺寸           | string   | large, small | |
-| disabled | 是否禁用计数器        | boolean |  | false |
+| value    | 绑定值         | number | — | — |
+| min      | 设置计数器允许的最小值 | number | — | 0 |
+| max      | 设置计数器允许的最大值 | number | — | Infinity |
+| step     | 计数器步长           | number   | — | 1 |
+| size     | 计数器尺寸           | string   | large, small | — |
+| disabled | 是否禁用计数器        | boolean | — | false |
+
+### Events
+| 事件名称 | 说明 | 回调参数 |
+|---------|--------|---------|
+| change | 绑定值被改变时触发 | 最后变更的值 |

+ 61 - 21
packages/input-number/src/input-number.vue

@@ -7,7 +7,6 @@
   >
     <el-input
       v-model="currentValue"
-      @onchange="handleChange"
       :disabled="disabled"
       :size="size"
       :number="true"
@@ -41,7 +40,7 @@
     name: 'ElInputNumber',
     props: {
       value: {
-        type: Number
+        default: 1
       },
       step: {
         type: Number,
@@ -91,42 +90,86 @@
     },
     data() {
       return {
-        currentValue: null,
+        currentValue: this.value,
         inputActive: false
       };
     },
     watch: {
-      value: {
-        immediate: true,
-        handler(val) {
-          this.currentValue = val;
-        }
-      },
-      currentValue(val) {
-        if (!isNaN(parseInt(val, 10))) {
-          this.$emit('input', parseInt(val, 10));
+      currentValue(newVal, oldVal) {
+        if (!isNaN(newVal) && newVal <= this.max && newVal >= this.min) {
+          this.$emit('change', newVal);
+          this.$emit('input', newVal);
+        } else {
+          this.$nextTick(() => {
+            this.currentValue = oldVal;
+          });
         }
       }
     },
     computed: {
       minDisabled() {
-        return this.value - this.step < this.min;
+        return this.currentValue - this.step < this.min;
       },
       maxDisabled() {
-        return this.value + this.step > this.max;
+        return this.currentValue + this.step > this.max;
       }
     },
     methods: {
+      accSub(arg1, arg2) {
+        var r1, r2, m, n;
+        try {
+          r1 = arg1.toString().split('.')[1].length;
+        } catch (e) {
+          r1 = 0;
+        }
+        try {
+          r2 = arg2.toString().split('.')[1].length;
+        } catch (e) {
+          r2 = 0;
+        }
+        m = Math.pow(10, Math.max(r1, r2));
+        n = (r1 >= r2) ? r1 : r2;
+        return parseFloat(((arg1 * m - arg2 * m) / m).toFixed(n));
+      },
+      accAdd(arg1, arg2) {
+        var r1, r2, m, c;
+        try {
+          r1 = arg1.toString().split('.')[1].length;
+        } catch (e) {
+          r1 = 0;
+        }
+        try {
+          r2 = arg2.toString().split('.')[1].length;
+        } catch (e) {
+          r2 = 0;
+        }
+        c = Math.abs(r1 - r2);
+        m = Math.pow(10, Math.max(r1, r2));
+        if (c > 0) {
+          var cm = Math.pow(10, c);
+          if (r1 > r2) {
+            arg1 = Number(arg1.toString().replace('.', ''));
+            arg2 = Number(arg2.toString().replace('.', '')) * cm;
+          } else {
+            arg1 = Number(arg1.toString().replace('.', '')) * cm;
+            arg2 = Number(arg2.toString().replace('.', ''));
+          }
+        } else {
+          arg1 = Number(arg1.toString().replace('.', ''));
+          arg2 = Number(arg2.toString().replace('.', ''));
+        }
+        return (arg1 + arg2) / m;
+      },
       increase() {
-        if (this.value + this.step > this.max || this.disabled) return;
-        this.currentValue += this.step;
+        if (this.currentValue + this.step > this.max || this.disabled) return;
+        this.currentValue = this.accAdd(this.step, this.currentValue);
         if (this.maxDisabled) {
           this.inputActive = false;
         }
       },
       decrease() {
-        if (this.value - this.step < this.min || this.disabled) return;
-        this.currentValue -= this.step;
+        if (this.currentValue - this.step < this.min || this.disabled) return;
+        this.currentValue = this.accSub(this.currentValue, this.step);
         if (this.minDisabled) {
           this.inputActive = false;
         }
@@ -140,9 +183,6 @@
         if (!this.disabled && !disabled) {
           this.inputActive = false;
         }
-      },
-      handleChange(value) {
-        this.$emit('onchange', value);
       }
     }
   };