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

196 lines
5.2 KiB
Vue
Raw Normal View History

2016-07-27 06:15:02 +00:00
<template>
<div class="el-input-number"
:class="[
2016-10-25 03:33:39 +00:00
size ? 'el-input-number--' + size : '',
{ 'is-disabled': disabled },
{ 'is-without-controls': !controls}
2016-07-27 06:15:02 +00:00
]"
>
<span
v-if="controls"
2016-07-27 06:15:02 +00:00
class="el-input-number__decrease el-icon-minus"
:class="{'is-disabled': minDisabled}"
2016-08-11 07:51:13 +00:00
v-repeat-click="decrease"
2016-07-27 06:15:02 +00:00
>
</span>
<span
v-if="controls"
2016-07-27 06:15:02 +00:00
class="el-input-number__increase el-icon-plus"
:class="{'is-disabled': maxDisabled}"
2016-08-11 07:51:13 +00:00
v-repeat-click="increase"
2016-07-27 06:15:02 +00:00
>
</span>
<el-input
2017-01-10 16:39:35 +00:00
:value="currentValue"
@keydown.up.native="increase"
@keydown.down.native="decrease"
@blur="handleBlur"
2017-01-10 16:39:35 +00:00
@input="handleInput"
:disabled="disabled"
:size="size"
:max="max"
:min="min"
2016-12-27 11:14:22 +00:00
ref="input"
>
<template slot="prepend" v-if="$slots.prepend">
<slot name="prepend"></slot>
</template>
<template slot="append" v-if="$slots.append">
<slot name="append"></slot>
</template>
</el-input>
2016-07-27 06:15:02 +00:00
</div>
</template>
<script>
2016-10-25 13:35:41 +00:00
import ElInput from 'element-ui/packages/input';
2016-12-26 03:41:15 +00:00
import { once, on } from 'element-ui/src/utils/dom';
2016-07-27 06:15:02 +00:00
export default {
name: 'ElInputNumber',
directives: {
repeatClick: {
2016-08-11 07:51:13 +00:00
bind(el, binding, vnode) {
2016-07-27 06:15:02 +00:00
let interval = null;
let startTime;
const handler = () => vnode.context[binding.expression].apply();
2016-12-26 02:45:20 +00:00
const clear = () => {
2016-07-27 06:15:02 +00:00
if (new Date() - startTime < 100) {
handler();
}
clearInterval(interval);
interval = null;
};
2016-12-26 02:45:20 +00:00
on(el, 'mousedown', () => {
2016-07-27 06:15:02 +00:00
startTime = new Date();
once(document, 'mouseup', clear);
2016-12-26 02:45:20 +00:00
interval = setInterval(handler, 100);
2016-07-27 06:15:02 +00:00
});
}
}
},
components: {
ElInput
},
props: {
step: {
type: Number,
default: 1
},
max: {
type: Number,
default: Infinity
},
min: {
type: Number,
default: -Infinity
},
value: {
default: 0
},
disabled: Boolean,
size: String,
controls: {
type: Boolean,
default: true
}
},
2016-07-27 06:15:02 +00:00
data() {
// correct the init value
let value = this.value;
if (value < this.min) {
this.$emit('input', this.min);
value = this.min;
}
if (value > this.max) {
this.$emit('input', this.max);
value = this.max;
}
2016-07-27 06:15:02 +00:00
return {
currentValue: value
2016-07-27 06:15:02 +00:00
};
},
2016-08-11 07:51:13 +00:00
watch: {
2017-01-10 16:39:35 +00:00
value(value) {
const newVal = Number(value);
if (!isNaN(newVal) && newVal <= this.max && newVal >= this.min) {
this.currentValue = newVal;
2016-08-11 07:51:13 +00:00
}
}
},
2016-07-27 06:15:02 +00:00
computed: {
minDisabled() {
return this._decrease(this.value, this.step) < this.min;
2016-07-27 06:15:02 +00:00
},
maxDisabled() {
return this._increase(this.value, this.step) > this.max;
},
precision() {
const { value, step, getPrecision } = this;
return Math.max(getPrecision(value), getPrecision(step));
2016-07-27 06:15:02 +00:00
}
},
methods: {
toPrecision(num, precision) {
if (precision === undefined) precision = this.precision;
return parseFloat(parseFloat(Number(num).toFixed(precision)));
2016-09-01 07:56:04 +00:00
},
getPrecision(value) {
const valueString = value.toString();
const dotPosition = valueString.indexOf('.');
let precision = 0;
if (dotPosition !== -1) {
precision = valueString.length - dotPosition - 1;
2016-09-01 07:56:04 +00:00
}
return precision;
},
_increase(val, step) {
if (typeof val !== 'number') return this.currentValue;
const precisionFactor = Math.pow(10, this.precision);
return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor);
},
_decrease(val, step) {
if (typeof val !== 'number') return this.currentValue;
const precisionFactor = Math.pow(10, this.precision);
return this.toPrecision((precisionFactor * val - precisionFactor * step) / precisionFactor);
2016-09-01 07:56:04 +00:00
},
2016-07-27 06:15:02 +00:00
increase() {
if (this.disabled || this.maxDisabled) return;
2016-11-24 06:48:56 +00:00
const value = this.value || 0;
const newVal = this._increase(value, this.step);
if (newVal > this.max) return;
2017-01-10 16:39:35 +00:00
this.setCurrentValue(newVal);
2016-07-27 06:15:02 +00:00
},
decrease() {
if (this.disabled || this.minDisabled) return;
2016-11-24 06:48:56 +00:00
const value = this.value || 0;
const newVal = this._decrease(value, this.step);
if (newVal < this.min) return;
2017-01-10 16:39:35 +00:00
this.setCurrentValue(newVal);
},
handleBlur() {
2016-12-27 11:14:22 +00:00
this.$refs.input.setCurrentValue(this.currentValue);
2017-01-10 16:39:35 +00:00
},
setCurrentValue(newVal) {
const oldVal = this.currentValue;
if (newVal <= this.max && newVal >= this.min && oldVal !== newVal) {
this.$emit('change', newVal, oldVal);
this.$emit('input', newVal);
this.currentValue = newVal;
}
},
handleInput(value) {
const newVal = Number(value);
if (!isNaN(newVal)) {
this.setCurrentValue(newVal);
}
2016-07-27 06:15:02 +00:00
}
}
};
</script>