mirror of https://github.com/ElemeFE/element
InputNumber: add precision attribute (#11281)
parent
66f90b9e37
commit
bcfb1d3c71
|
@ -99,6 +99,31 @@ Allows you to define incremental steps.
|
|||
```
|
||||
:::
|
||||
|
||||
### Precision
|
||||
|
||||
:::demo Add `precision` attribute to set the precision of input value.
|
||||
|
||||
```html
|
||||
<template>
|
||||
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
num9: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::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 |
|
||||
|
|
|
@ -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
|
||||
<template>
|
||||
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
num9: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::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 |
|
||||
|
|
|
@ -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
|
||||
<template>
|
||||
<el-input-number v-model="num9" :precision="2" :step="0.1" :max="10"></el-input-number>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
num9: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::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 |
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</span>
|
||||
<el-input
|
||||
ref="input"
|
||||
:value="currentValue"
|
||||
:value="currentInputValue"
|
||||
:disabled="inputNumberDisabled"
|
||||
:size="inputNumberSize"
|
||||
:max="max"
|
||||
|
@ -96,7 +96,13 @@
|
|||
default: ''
|
||||
},
|
||||
name: String,
|
||||
label: String
|
||||
label: String,
|
||||
precision: {
|
||||
type: Number,
|
||||
validator(val) {
|
||||
return val >= 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);
|
||||
|
|
|
@ -220,6 +220,51 @@ describe('InputNumber', () => {
|
|||
done();
|
||||
});
|
||||
});
|
||||
describe('precision', () => {
|
||||
it('precision is 2', () => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input-number v-model="value" :max="8" :precision="2">
|
||||
</el-input-number>
|
||||
`,
|
||||
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: `
|
||||
<el-input-number v-model="value" :max="8" :precision="0" :step="0.1">
|
||||
</el-input-number>
|
||||
`,
|
||||
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: `
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue