Skip to content

Commit bcfb1d3

Browse files
ziyoungLeopoldthecoder
authored andcommitted
InputNumber: add precision attribute (#11281)
1 parent 66f90b9 commit bcfb1d3

File tree

6 files changed

+171
-12
lines changed

6 files changed

+171
-12
lines changed

examples/docs/en-US/input-number.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,31 @@ Allows you to define incremental steps.
9999
```
100100
:::
101101

102+
### Precision
103+
104+
:::demo Add `precision` attribute to set the precision of input value.
105+
106+
```html
107+
<template>
108+
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
109+
</template>
110+
<script>
111+
export default {
112+
data() {
113+
return {
114+
num9: 1
115+
}
116+
}
117+
};
118+
</script>
119+
```
120+
121+
:::
122+
123+
:::tip
124+
The value of `precision` must be a positive integer and should not be less than the decimal places of `step`.
125+
:::
126+
102127
### Size
103128

104129
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`.
159184
|min | the minimum allowed value | number || `-Infinity` |
160185
|max | the maximum allowed value | number || `Infinity` |
161186
|step | incremental step | number || 1 |
187+
|precision | precision of input value | number |||
162188
|size | size of the component | string | large/small||
163189
|disabled| whether the component is disabled | boolean || false |
164190
|controls| whether to enable the control buttons | boolean || true |

examples/docs/es/input-number.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,31 @@ Le permite definir el nivel de incremento de los saltos.
9999
```
100100
:::
101101

102+
### Precision
103+
104+
:::demo Add `precision` attribute to set the precision of input value.
105+
106+
```html
107+
<template>
108+
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
109+
</template>
110+
<script>
111+
export default {
112+
data() {
113+
return {
114+
num9: 1
115+
}
116+
}
117+
};
118+
</script>
119+
```
120+
121+
:::
122+
123+
:::tip
124+
The value of `precision` must be a positive integer and should not be less than the decimal places of `step`.
125+
:::
126+
102127
### Tamaño
103128

104129
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
160185
| min | el valor mínimo permitido | number || `-Infinity` |
161186
| max | el valor maximo permitido | number || `Infinity` |
162187
| step | incremento (salto) | number || 1 |
188+
| precision | precision of input value | number |||
163189
| size | tamaño del componente | string | large/small ||
164190
| disabled | si el componente esta deshabilitado | boolean || false |
165191
| controls | si se activan los botones de control | boolean || true |

examples/docs/zh-CN/input-number.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
num5: 1,
1010
num6: 1,
1111
num7: 1,
12-
num8: 1
12+
num8: 1,
13+
num9: 1
1314
}
1415
},
1516
methods: {
@@ -97,6 +98,31 @@
9798
```
9899
:::
99100

101+
### 精度
102+
103+
:::demo 设置 `precision` 属性可以控制数值精度,接收一个 `Number`
104+
105+
```html
106+
<template>
107+
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
108+
</template>
109+
<script>
110+
export default {
111+
data() {
112+
return {
113+
num9: 1
114+
}
115+
}
116+
};
117+
</script>
118+
```
119+
120+
:::
121+
122+
:::tip
123+
`precision` 的值必须是一个正整数,并且不能小于 `step` 的小数位数。
124+
:::
125+
100126
### 尺寸
101127

102128
额外提供了 `medium``small``mini` 三种尺寸的数字输入框
@@ -156,6 +182,7 @@
156182
| min | 设置计数器允许的最小值 | number || -Infinity |
157183
| max | 设置计数器允许的最大值 | number || Infinity |
158184
| step | 计数器步长 | number || 1 |
185+
| precision| 数值精度 | number |||
159186
| size | 计数器尺寸 | string | large, small ||
160187
| disabled | 是否禁用计数器 | boolean || false |
161188
| controls | 是否使用控制按钮 | boolean || true |

packages/input-number/src/input-number.vue

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
</span>
2929
<el-input
3030
ref="input"
31-
:value="currentValue"
31+
:value="currentInputValue"
3232
:disabled="inputNumberDisabled"
3333
:size="inputNumberSize"
3434
:max="max"
@@ -96,7 +96,13 @@
9696
default: ''
9797
},
9898
name: String,
99-
label: String
99+
label: String,
100+
precision: {
101+
type: Number,
102+
validator(val) {
103+
return val >= 0 && val === parseInt(val, 10);
104+
}
105+
}
100106
},
101107
data() {
102108
return {
@@ -108,7 +114,14 @@
108114
immediate: true,
109115
handler(value) {
110116
let newVal = value === undefined ? value : Number(value);
111-
if (newVal !== undefined && isNaN(newVal)) return;
117+
if (newVal !== undefined) {
118+
if (isNaN(newVal)) {
119+
return;
120+
}
121+
if (this.precision !== undefined) {
122+
newVal = this.toPrecision(newVal, this.precision);
123+
}
124+
}
112125
if (newVal >= this.max) newVal = this.max;
113126
if (newVal <= this.min) newVal = this.min;
114127
this.currentValue = newVal;
@@ -123,9 +136,17 @@
123136
maxDisabled() {
124137
return this._increase(this.value, this.step) > this.max;
125138
},
126-
precision() {
127-
const { value, step, getPrecision } = this;
128-
return Math.max(getPrecision(value), getPrecision(step));
139+
numPrecision() {
140+
const { value, step, getPrecision, precision } = this;
141+
const stepPrecision = getPrecision(step);
142+
if (precision !== undefined) {
143+
if (stepPrecision > precision) {
144+
console.warn('[Element Warn][InputNumber]precision should not be less than the decimal places of step');
145+
}
146+
return precision;
147+
} else {
148+
return Math.max(getPrecision(value), stepPrecision);
149+
}
129150
},
130151
controlsAtRight() {
131152
return this.controlsPosition === 'right';
@@ -138,11 +159,19 @@
138159
},
139160
inputNumberDisabled() {
140161
return this.disabled || (this.elForm || {}).disabled;
162+
},
163+
currentInputValue() {
164+
const currentValue = this.currentValue;
165+
if (typeof currentValue === 'number' && this.precision !== undefined) {
166+
return currentValue.toFixed(this.precision);
167+
} else {
168+
return currentValue;
169+
}
141170
}
142171
},
143172
methods: {
144173
toPrecision(num, precision) {
145-
if (precision === undefined) precision = this.precision;
174+
if (precision === undefined) precision = this.numPrecision;
146175
return parseFloat(parseFloat(Number(num).toFixed(precision)));
147176
},
148177
getPrecision(value) {
@@ -158,14 +187,14 @@
158187
_increase(val, step) {
159188
if (typeof val !== 'number' && val !== undefined) return this.currentValue;
160189
161-
const precisionFactor = Math.pow(10, this.precision);
190+
const precisionFactor = Math.pow(10, this.numPrecision);
162191
// Solve the accuracy problem of JS decimal calculation by converting the value to integer.
163192
return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor);
164193
},
165194
_decrease(val, step) {
166195
if (typeof val !== 'number' && val !== undefined) return this.currentValue;
167196
168-
const precisionFactor = Math.pow(10, this.precision);
197+
const precisionFactor = Math.pow(10, this.numPrecision);
169198
170199
return this.toPrecision((precisionFactor * val - precisionFactor * step) / precisionFactor);
171200
},
@@ -183,17 +212,20 @@
183212
},
184213
handleBlur(event) {
185214
this.$emit('blur', event);
186-
this.$refs.input.setCurrentValue(this.currentValue);
215+
this.$refs.input.setCurrentValue(this.currentInputValue);
187216
},
188217
handleFocus(event) {
189218
this.$emit('focus', event);
190219
},
191220
setCurrentValue(newVal) {
192221
const oldVal = this.currentValue;
222+
if (typeof newVal === 'number' && this.precision !== undefined) {
223+
newVal = this.toPrecision(newVal, this.precision);
224+
}
193225
if (newVal >= this.max) newVal = this.max;
194226
if (newVal <= this.min) newVal = this.min;
195227
if (oldVal === newVal) {
196-
this.$refs.input.setCurrentValue(this.currentValue);
228+
this.$refs.input.setCurrentValue(this.currentInputValue);
197229
return;
198230
}
199231
this.$emit('input', newVal);

test/unit/specs/input-number.spec.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,51 @@ describe('InputNumber', () => {
220220
done();
221221
});
222222
});
223+
describe('precision', () => {
224+
it('precision is 2', () => {
225+
vm = createVue({
226+
template: `
227+
<el-input-number v-model="value" :max="8" :precision="2">
228+
</el-input-number>
229+
`,
230+
data() {
231+
return {
232+
value: 6.999
233+
};
234+
}
235+
}, true);
236+
expect(vm.value === 7);
237+
expect(vm.$el.querySelector('input').value).to.be.equal('7.00');
238+
});
239+
240+
it('precision greater than the precision of step', done => {
241+
vm = createVue({
242+
template: `
243+
<el-input-number v-model="value" :max="8" :precision="0" :step="0.1">
244+
</el-input-number>
245+
`,
246+
data() {
247+
return {
248+
value: 6.999
249+
};
250+
}
251+
}, true);
252+
const input = vm.$el.querySelector('input');
253+
const btnIncrease = vm.$el.querySelector('.el-input-number__increase');
254+
255+
expect(vm.value === 7);
256+
expect(input.value).to.be.equal('7');
257+
258+
triggerEvent(btnIncrease, 'mousedown');
259+
triggerClick(document, 'mouseup');
260+
261+
vm.$nextTick(_ => {
262+
expect(vm.value).to.be.equal(7);
263+
expect(input.value).to.be.equal('7');
264+
done();
265+
});
266+
});
267+
});
223268
it('controls', () => {
224269
vm = createVue({
225270
template: `

types/input-number.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export declare class ElInputNumber extends ElementUIComponent {
3434
/** Same as name in native input */
3535
name: string
3636

37+
/** Precision of input value */
38+
precision: Number
39+
3740
/**
3841
* Focus the Input component
3942
*/

0 commit comments

Comments
 (0)