input-number.vue
<template>
<div
@dragstart.prevent
:class="[
'el-input-number',
inputNumberSize ? 'el-input-number--' + inputNumberSize : '',
{ 'is-disabled': inputNumberDisabled },
{ 'is-without-controls': !controls },
{ 'is-controls-right': controlsAtRight }
]">
<span
class="el-input-number__decrease"
role="button"
v-if="controls"
v-repeat-click="decrease"
:class="{'is-disabled': minDisabled}"
@keydown.enter="decrease">
<i :class="`el-icon-${controlsAtRight ? 'arrow-down' : 'minus'}`"></i>
</span>
<span
class="el-input-number__increase"
role="button"
v-if="controls"
v-repeat-click="increase"
:class="{'is-disabled': maxDisabled}"
@keydown.enter="increase">
<i :class="`el-icon-${controlsAtRight ? 'arrow-up' : 'plus'}`"></i>
</span>
<el-input
ref="input"
:value="displayValue"
:placeholder="placeholder"
:disabled="inputNumberDisabled"
:size="inputNumberSize"
:max="max"
:min="min"
:name="name"
:label="label"
@keydown.up.native.prevent="increase"
@keydown.down.native.prevent="decrease"
@blur="handleBlur"
@focus="handleFocus"
@input="handleInput"
@change="handleInputChange">
</el-input>
</div>
</template>
<script>
import ElInput from 'element-ui/packages/input';
import Focus from 'element-ui/src/mixins/focus'; import RepeatClick from 'element-ui/src/directives/repeat-click'; export default { name: 'ElInputNumber', mixins: [Focus('input')], inject: { elForm: { default: '' }, elFormItem: { default: '' }}, Directives: {repeatClick: RepeatClick}, Components: ElInput {}, The props: {// step counter step: {type: Number The, default : . 1 }, // if only the input a multiple step stepStrictly : {type: Boolean, default : to false }, // set the maximum allowed counter max: {type: Number the, default : Infinity}, // set the minimum allowed value counter min: {type: Number the, default : - Infinity }, // value / v-model binding value value: {}, // whether the counter is disabled disabled: Boolean, // counter Large size String, Small size: String, // whether the control button controls: {type: Boolean , default : to true }, // right control button position String controlsPosition: {type: String, default: '' }, // native property name: String, // label text input box associated label: String, // default input box placeholder placeholder: String, // numerical precision precision: {type: Number, validator (val) return { Val > = 0 && Val === the parseInt (Val, 10 );}}}, Data () {return {currentValue: 0 , userInput: null };}, Watch: {// vaue value variation value: { // trigger an immediate load immediate: to true , // custom function Handler (value) {the let newVal = value === undefined ? value: Number The (value); IF (newVal ==! undefined) { if (isNaN(newVal)) { return; } // 是否只能输入 step 的倍数 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); } } if (newVal >= this.max) newVal = this.max; if (newVal <= this.min) newVal = this.min; this.currentValue = newVal; this.userInput = null; this.$emit('input', newVal); } } }, computed: { // 不能小于最小数 minDisabled() { return this._decrease(this.value, this.step) < this.min; }, // 不能大于最大数 maxDisabled() { return this._increase(this.value, this.step) > this.max; }, 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.controls && this.controlsPosition === 'right'; }, _elFormItemSize() { return (this.elFormItem || {}).elFormItemSize; }, inputNumberSize() { return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; }, inputNumberDisabled() { return this.disabled || (this.elForm || {}).disabled; }, displayValue() { if (this.userInput !== null) { return this.userInput; } let currentValue = this.currentValue; if (typeof currentValue === 'number') { // 如果只能输入 step 的倍数 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: { // 截取为传入的位数 toPrecision(num, precision) { if (precision === undefined) precision = this.numPrecision; return parseFloat(Number(num).toFixed(precision)); }, // 获取小数点后面还有几位 getPrecision(value) { if (value === undefined) return 0; const valueString = value.toString(); const dotPosition = valueString.indexOf('.