diff --git a/examples/docs/en-US/input-number.md b/examples/docs/en-US/input-number.md
index 3d9a20c11..6e7081823 100644
--- a/examples/docs/en-US/input-number.md
+++ b/examples/docs/en-US/input-number.md
@@ -99,6 +99,31 @@ Allows you to define incremental steps.
```
:::
+### Precision
+
+:::demo Add `precision` attribute to set the precision of input value.
+
+```html
+
+
+
+
+```
+
+:::
+
+:::tip
+The value of `precision` must be a positive integer and should not be less than the decimal places of `step`.
+:::
+
### Size
Use attribute `size` to set additional sizes with `medium`, `small` or `mini`.
@@ -159,6 +184,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 |
+|precision | precision of input value | number | — | — |
|size | size of the component | string | large/small| — |
|disabled| whether the component is disabled | boolean | — | false |
|controls| whether to enable the control buttons | boolean | — | true |
diff --git a/examples/docs/es/input-number.md b/examples/docs/es/input-number.md
index 929fc4812..f0bdb6543 100644
--- a/examples/docs/es/input-number.md
+++ b/examples/docs/es/input-number.md
@@ -99,6 +99,31 @@ Le permite definir el nivel de incremento de los saltos.
```
:::
+### Precision
+
+:::demo Add `precision` attribute to set the precision of input value.
+
+```html
+
+
+
+
+```
+
+:::
+
+:::tip
+The value of `precision` must be a positive integer and should not be less than the decimal places of `step`.
+:::
+
### Tamaño
Utilice el atributo `size` para establecer tamaños adicionales con `medium`, `small` o `mini`.
@@ -160,6 +185,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 |
+| precision | precision of input value | number | — | — |
| size | tamaño del componente | string | large/small | — |
| disabled | si el componente esta deshabilitado | boolean | — | false |
| controls | si se activan los botones de control | boolean | — | true |
diff --git a/examples/docs/zh-CN/input-number.md b/examples/docs/zh-CN/input-number.md
index 4cf1d5ca2..10c9ef1d3 100644
--- a/examples/docs/zh-CN/input-number.md
+++ b/examples/docs/zh-CN/input-number.md
@@ -9,7 +9,8 @@
num5: 1,
num6: 1,
num7: 1,
- num8: 1
+ num8: 1,
+ num9: 1
}
},
methods: {
@@ -97,6 +98,31 @@
```
:::
+### 精度
+
+:::demo 设置 `precision` 属性可以控制数值精度,接收一个 `Number`。
+
+```html
+
+
+
+
+```
+
+:::
+
+:::tip
+`precision` 的值必须是一个正整数,并且不能小于 `step` 的小数位数。
+:::
+
### 尺寸
额外提供了 `medium`、`small`、`mini` 三种尺寸的数字输入框
@@ -156,6 +182,7 @@
| min | 设置计数器允许的最小值 | number | — | -Infinity |
| max | 设置计数器允许的最大值 | number | — | Infinity |
| step | 计数器步长 | number | — | 1 |
+| precision| 数值精度 | number | — | — |
| size | 计数器尺寸 | string | large, small | — |
| disabled | 是否禁用计数器 | boolean | — | false |
| controls | 是否使用控制按钮 | boolean | — | true |
diff --git a/packages/input-number/src/input-number.vue b/packages/input-number/src/input-number.vue
index 8f2a9873d..1dd52de3a 100644
--- a/packages/input-number/src/input-number.vue
+++ b/packages/input-number/src/input-number.vue
@@ -28,7 +28,7 @@
= 0 && val === parseInt(val, 10);
+ }
+ }
},
data() {
return {
@@ -108,7 +114,14 @@
immediate: true,
handler(value) {
let newVal = value === undefined ? value : Number(value);
- if (newVal !== undefined && isNaN(newVal)) return;
+ if (newVal !== undefined) {
+ if (isNaN(newVal)) {
+ return;
+ }
+ if (this.precision !== undefined) {
+ newVal = this.toPrecision(newVal, this.precision);
+ }
+ }
if (newVal >= this.max) newVal = this.max;
if (newVal <= this.min) newVal = this.min;
this.currentValue = newVal;
@@ -123,9 +136,17 @@
maxDisabled() {
return this._increase(this.value, this.step) > this.max;
},
- precision() {
- const { value, step, getPrecision } = this;
- return Math.max(getPrecision(value), getPrecision(step));
+ numPrecision() {
+ const { value, step, getPrecision, precision } = this;
+ const stepPrecision = getPrecision(step);
+ if (precision !== undefined) {
+ if (stepPrecision > precision) {
+ console.warn('[Element Warn][InputNumber]precision should not be less than the decimal places of step');
+ }
+ return precision;
+ } else {
+ return Math.max(getPrecision(value), stepPrecision);
+ }
},
controlsAtRight() {
return this.controlsPosition === 'right';
@@ -138,11 +159,19 @@
},
inputNumberDisabled() {
return this.disabled || (this.elForm || {}).disabled;
+ },
+ currentInputValue() {
+ const currentValue = this.currentValue;
+ if (typeof currentValue === 'number' && this.precision !== undefined) {
+ return currentValue.toFixed(this.precision);
+ } else {
+ return currentValue;
+ }
}
},
methods: {
toPrecision(num, precision) {
- if (precision === undefined) precision = this.precision;
+ if (precision === undefined) precision = this.numPrecision;
return parseFloat(parseFloat(Number(num).toFixed(precision)));
},
getPrecision(value) {
@@ -158,14 +187,14 @@
_increase(val, step) {
if (typeof val !== 'number' && val !== undefined) return this.currentValue;
- const precisionFactor = Math.pow(10, this.precision);
+ const precisionFactor = Math.pow(10, this.numPrecision);
// Solve the accuracy problem of JS decimal calculation by converting the value to integer.
return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor);
},
_decrease(val, step) {
if (typeof val !== 'number' && val !== undefined) return this.currentValue;
- const precisionFactor = Math.pow(10, this.precision);
+ const precisionFactor = Math.pow(10, this.numPrecision);
return this.toPrecision((precisionFactor * val - precisionFactor * step) / precisionFactor);
},
@@ -183,17 +212,20 @@
},
handleBlur(event) {
this.$emit('blur', event);
- this.$refs.input.setCurrentValue(this.currentValue);
+ this.$refs.input.setCurrentValue(this.currentInputValue);
},
handleFocus(event) {
this.$emit('focus', event);
},
setCurrentValue(newVal) {
const oldVal = this.currentValue;
+ if (typeof newVal === 'number' && this.precision !== undefined) {
+ newVal = this.toPrecision(newVal, this.precision);
+ }
if (newVal >= this.max) newVal = this.max;
if (newVal <= this.min) newVal = this.min;
if (oldVal === newVal) {
- this.$refs.input.setCurrentValue(this.currentValue);
+ this.$refs.input.setCurrentValue(this.currentInputValue);
return;
}
this.$emit('input', newVal);
diff --git a/test/unit/specs/input-number.spec.js b/test/unit/specs/input-number.spec.js
index deef42b73..4ba16be1e 100644
--- a/test/unit/specs/input-number.spec.js
+++ b/test/unit/specs/input-number.spec.js
@@ -220,6 +220,51 @@ describe('InputNumber', () => {
done();
});
});
+ describe('precision', () => {
+ it('precision is 2', () => {
+ vm = createVue({
+ template: `
+
+
+ `,
+ data() {
+ return {
+ value: 6.999
+ };
+ }
+ }, true);
+ expect(vm.value === 7);
+ expect(vm.$el.querySelector('input').value).to.be.equal('7.00');
+ });
+
+ it('precision greater than the precision of step', done => {
+ vm = createVue({
+ template: `
+
+
+ `,
+ data() {
+ return {
+ value: 6.999
+ };
+ }
+ }, true);
+ const input = vm.$el.querySelector('input');
+ const btnIncrease = vm.$el.querySelector('.el-input-number__increase');
+
+ expect(vm.value === 7);
+ expect(input.value).to.be.equal('7');
+
+ triggerEvent(btnIncrease, 'mousedown');
+ triggerClick(document, 'mouseup');
+
+ vm.$nextTick(_ => {
+ expect(vm.value).to.be.equal(7);
+ expect(input.value).to.be.equal('7');
+ done();
+ });
+ });
+ });
it('controls', () => {
vm = createVue({
template: `
diff --git a/types/input-number.d.ts b/types/input-number.d.ts
index 53fbd3727..deec6f59b 100644
--- a/types/input-number.d.ts
+++ b/types/input-number.d.ts
@@ -34,6 +34,9 @@ export declare class ElInputNumber extends ElementUIComponent {
/** Same as name in native input */
name: string
+ /** Precision of input value */
+ precision: Number
+
/**
* Focus the Input component
*/