Эх сурвалжийг харах

InputNumber: add step-strictly attribute (#15050)

luckyCao 6 жил өмнө
parent
commit
1fe6849a63

+ 21 - 0
examples/docs/en-US/input-number.md

@@ -69,6 +69,26 @@ Allows you to define incremental steps.
 ```
 :::
 
+### Step strictly
+
+:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step.
+
+```html
+<template>
+  <el-input-number v-model="num" :step="2" step-strictly></el-input-number>
+</template>
+<script>
+  export default {
+    data() {
+      return {
+        num: 2
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### Precision
 
 :::demo Add `precision` attribute to set the precision of input value.
@@ -154,6 +174,7 @@ Use attribute `size` to set additional sizes with `medium`, `small` or `mini`.
 |min | the minimum allowed value | number | — | `-Infinity` |
 |max | the maximum allowed value | number | — | `Infinity` |
 |step | incremental step | number | — | 1 |
+|step-strictly | whether input value can only be multiple of step | number   | — | false |
 |precision | precision of input value | number | — | — |
 |size | size of the component | string | large/small| — |
 |disabled| whether the component is disabled | boolean | — | false |

+ 21 - 0
examples/docs/es/input-number.md

@@ -69,6 +69,26 @@ Le permite definir el nivel de incremento de los saltos.
 ```
 :::
 
+### Step strictly
+
+:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step.
+
+```html
+<template>
+  <el-input-number v-model="num" :step="2" step-strictly></el-input-number>
+</template>
+<script>
+  export default {
+    data() {
+      return {
+        num: 2
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### Precision
 
 :::demo Add `precision` attribute to set the precision of input value.
@@ -155,6 +175,7 @@ Utilice el atributo `size` para establecer tamaños adicionales con `medium`, `s
 | min               | el valor mínimo permitido                | number  | —                 | `-Infinity`  |
 | max               | el valor maximo permitido                | number  | —                 | `Infinity`  |
 | step              | incremento (salto)                       | number  | —                 | 1           |
+| step-strictly  | whether input value can can only be multiple of step | number  | —                 | false       |
 | precision         | precisión del valor del input | number  | —                 | —           |
 | size              | tamaño del componente                    | string  | large/small       | —           |
 | disabled          | si el componente esta deshabilitado      | boolean | —                 | false       |

+ 21 - 0
examples/docs/fr-FR/input-number.md

@@ -69,6 +69,26 @@ Vous pouvez déterminer un pas pour le champs.
 ```
 :::
 
+### Step strictly
+
+:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step.
+
+```html
+<template>
+  <el-input-number v-model="num" :step="2" step-strictly></el-input-number>
+</template>
+<script>
+  export default {
+    data() {
+      return {
+        num: 2
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### Précision
 
 :::demo Ajoutez l'attribut `precision` pour régler la précision du champs.
@@ -154,6 +174,7 @@ Utilisez l'attribut `size` pour régler la taille avec `medium`, `small` ou `min
 | min | La valeur minimale autorisée. | number | — | `-Infinity` |
 | max | La valeur maximale autorisée. | number | — | `Infinity` |
 | step | Le pas pour l'incrémentation. | number | — | 1 |
+| step-strictly | whether input value can only be multiple of step | number   | — | false |
 | precision | La précision de la valeur. | number | — | — |
 | size | La taille du composant. | string | large/small| — |
 | disabled| Si le composant est désactivé. | boolean | — | false |

+ 21 - 0
examples/docs/zh-CN/input-number.md

@@ -68,6 +68,26 @@
 ```
 :::
 
+### 严格步数
+
+:::demo `step-strictly`属性接受一个`Boolean`。如果这个属性被设置为`true`,则只能输入步数的倍数。
+
+```html
+<template>
+  <el-input-number v-model="num" :step="2" step-strictly></el-input-number>
+</template>
+<script>
+  export default {
+    data() {
+      return {
+        num: 2
+      }
+    }
+  };
+</script>
+```
+:::
+
 ### 精度
 
 :::demo 设置 `precision` 属性可以控制数值精度,接收一个 `Number`。
@@ -152,6 +172,7 @@
 | min      | 设置计数器允许的最小值 | number | — | -Infinity |
 | max      | 设置计数器允许的最大值 | number | — | Infinity |
 | step     | 计数器步长           | number   | — | 1 |
+| step-strictly | 是否只能输入 step 的倍数 | number   | — | false |
 | precision| 数值精度             | number   | — | — |
 | size     | 计数器尺寸           | string   | large, small | — |
 | disabled | 是否禁用计数器        | boolean | — | false |

+ 26 - 5
packages/input-number/src/input-number.vue

@@ -72,6 +72,10 @@
         type: Number,
         default: 1
       },
+      stepStrictly: {
+        type: Boolean,
+        default: false
+      },
       max: {
         type: Number,
         default: Infinity
@@ -116,6 +120,13 @@
             if (isNaN(newVal)) {
               return;
             }
+
+            if (this.stepStrictly) {
+              const stepPrecision = this.getPrecision(this.step);
+              const precisionFactor = Math.pow(10, stepPrecision);
+              newVal = Math.round(newVal / this.step) * precisionFactor * this.step / precisionFactor;
+            }
+
             if (this.precision !== undefined) {
               newVal = this.toPrecision(newVal, this.precision);
             }
@@ -163,12 +174,22 @@
         if (this.userInput !== null) {
           return this.userInput;
         }
-        const currentValue = this.currentValue;
-        if (typeof currentValue === 'number' && this.precision !== undefined) {
-          return currentValue.toFixed(this.precision);
-        } else {
-          return currentValue;
+
+        let currentValue = this.currentValue;
+
+        if (typeof currentValue === 'number') {
+          if (this.stepStrictly) {
+            const stepPrecision = this.getPrecision(this.step);
+            const precisionFactor = Math.pow(10, stepPrecision);
+            currentValue = Math.round(currentValue / this.step) * precisionFactor * this.step / precisionFactor;
+          }
+
+          if (this.precision !== undefined) {
+            currentValue = currentValue.toFixed(this.precision);
+          }
         }
+
+        return currentValue;
       }
     },
     methods: {

+ 24 - 1
test/unit/specs/input-number.spec.js

@@ -1,4 +1,4 @@
-import { createVue, triggerEvent, triggerClick, destroyVM } from '../util';
+import {createVue, triggerEvent, triggerClick, destroyVM, waitImmediate} from '../util';
 
 const DELAY = 1;
 
@@ -142,6 +142,29 @@ describe('InputNumber', () => {
       });
     });
   });
+  it('step strictly', async() => {
+    vm = createVue({
+      template: `
+        <el-input-number v-model="value" :step="1.2" step-strictly>
+        </el-input-number>
+      `,
+      data() {
+        return {
+          value: 5
+        };
+      }
+    }, true);
+
+    let input = vm.$el.querySelector('input');
+    await waitImmediate();
+    expect(vm.value).to.be.equal(4.8);
+    expect(input.value).to.be.equal('4.8');
+    vm.value = '8';
+
+    await waitImmediate();
+    expect(vm.value).to.be.equal(8.4);
+    expect(input.value).to.be.equal('8.4');
+  });
   it('min', done => {
     vm = createVue({
       template: `

+ 4 - 1
types/input-number.d.ts

@@ -35,7 +35,10 @@ export declare class ElInputNumber extends ElementUIComponent {
   name: string
 
   /** Precision of input value */
-  precision: Number
+  precision: number
+
+  /** whether input value can only be multiple of step */
+  stepStrictly: boolean
 
   /**
    * Focus the Input component