vant/packages/stepper/index.vue

131 lines
2.8 KiB
Vue

<template>
<div :class="b({ disabled })">
<button
:class="b('minus', { disabled: minusDisabled })"
@click="onChange('minus')"
/>
<input
type="number"
:class="b('input')"
:value="currentValue"
:disabled="disabled || disableInput"
@input="onInput"
@keypress="onKeypress"
>
<button
:class="b('plus', { disabled: plusDisabled })"
@click="onChange('plus')"
/>
</div>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'stepper',
props: {
value: {},
integer: Boolean,
disabled: Boolean,
disableInput: Boolean,
min: {
type: [String, Number],
default: 1
},
max: {
type: [String, Number],
default: Infinity
},
step: {
type: [String, Number],
default: 1
},
defaultValue: {
type: [String, Number],
default: 1
}
},
data() {
let value = this.value ? +this.value : +this.defaultValue;
const correctedValue = this.correctValue(value);
if (value !== correctedValue) {
value = correctedValue;
this.$emit('input', value);
}
return {
currentValue: value
};
},
computed: {
minusDisabled() {
const min = +this.min;
const step = +this.step;
const currentValue = +this.currentValue;
return min === currentValue || (currentValue - step) < min || this.disabled;
},
plusDisabled() {
const max = +this.max;
const step = +this.step;
const currentValue = +this.currentValue;
return max === currentValue || (currentValue + step) > max || this.disabled;
}
},
watch: {
value(val) {
if (val !== '') {
val = this.correctValue(+val);
if (val !== this.currentValue) {
this.currentValue = val;
}
}
}
},
methods: {
correctValue(value) {
return Number.isNaN(value)
? this.min
: Math.max(this.min, Math.min(this.max, value));
},
onInput(event) {
const { value } = event.target;
this.currentValue = value ? this.correctValue(+value) : value;
event.target.value = this.currentValue;
this.emitInput();
},
onChange(type) {
if ((this.minusDisabled && type === 'minus') || (this.plusDisabled && type === 'plus')) {
this.$emit('overlimit', type);
return;
}
const step = +this.step;
const currentValue = +this.currentValue;
this.currentValue = type === 'minus' ? (currentValue - step) : (currentValue + step);
this.emitInput();
this.$emit(type);
},
onKeypress(event) {
if (this.integer && event.keyCode === 46) {
event.preventDefault();
}
},
emitInput() {
this.$emit('input', this.currentValue);
this.$emit('change', this.currentValue);
}
}
});
</script>