|
|
<template>
|
|
|
<view class="cl-stepper" :data-index="index">
|
|
|
<view :class="'cl-stepper__minus ' + (disabled || min >= value ? 'cl-stepper__minus--disabled' : '')" @tap="reduce"></view>
|
|
|
<input type="number" :disabled="inputDisabled" class="cl-stepper__input" @blur="blur" :value="value" />
|
|
|
<view :class="'cl-stepper__plus ' + (disabled || value >= max ? 'cl-stepper__minus--disabled' : '')" @tap="plus"></view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
export default {
|
|
|
data() {
|
|
|
return {};
|
|
|
},
|
|
|
props: {
|
|
|
value: {
|
|
|
type: Number,
|
|
|
default: 0
|
|
|
},
|
|
|
min: {
|
|
|
type: Number,
|
|
|
default: 0
|
|
|
},
|
|
|
max: {
|
|
|
type: Number,
|
|
|
default: 10000
|
|
|
},
|
|
|
step: {
|
|
|
type: Number,
|
|
|
default: 1
|
|
|
},
|
|
|
disabled: {
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
inputDisabled: {
|
|
|
type: Boolean,
|
|
|
default: true
|
|
|
},
|
|
|
index: {
|
|
|
type: Number,
|
|
|
default: 0
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
//通过step属性设置每次点击增加或减少按钮时变化的值,默认为1
|
|
|
getScale() {
|
|
|
let scale = 1;
|
|
|
|
|
|
if (this.step != parseInt(this.step)) {
|
|
|
//微信小程序的小数计算会出现偏差导致产生很长的无限循环的数,在这块处理一下。
|
|
|
scale = Math.pow(10, (this.step + '').split('.')[1].length);
|
|
|
}
|
|
|
|
|
|
return scale;
|
|
|
},
|
|
|
|
|
|
//输入操作处理
|
|
|
blur: function (e) {
|
|
|
let value = e.detail.value;
|
|
|
|
|
|
if (value) {
|
|
|
value = +value;
|
|
|
|
|
|
if (value > this.max) {
|
|
|
value = this.max;
|
|
|
} else {
|
|
|
if (value < this.min) {
|
|
|
value = this.min;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
value = this.min;
|
|
|
}
|
|
|
|
|
|
if (value != this.value) {
|
|
|
this.setData({
|
|
|
valueClone: value
|
|
|
});
|
|
|
}
|
|
|
|
|
|
this.handleChange(value, 'blur');
|
|
|
},
|
|
|
calcNum: function (type) {
|
|
|
if (this.disabled) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const scale = this.getScale();
|
|
|
let num = this.value * scale;
|
|
|
let step = this.step * scale;
|
|
|
|
|
|
if (type === 'reduce') {
|
|
|
num -= step;
|
|
|
} else {
|
|
|
if (type === 'plus') {
|
|
|
num += step;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
let value = num / scale;
|
|
|
|
|
|
if (type === 'plus' && value < this.min) {
|
|
|
value = this.min;
|
|
|
} else {
|
|
|
if (type === 'reduce' && value > this.max) {
|
|
|
value = this.max;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (value < this.min || value > this.max) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this.handleChange(value, type);
|
|
|
},
|
|
|
//增加按钮处理
|
|
|
plus: function () {
|
|
|
this.calcNum('plus');
|
|
|
},
|
|
|
//减少按钮处理
|
|
|
reduce: function () {
|
|
|
this.calcNum('reduce');
|
|
|
},
|
|
|
|
|
|
//事件绑定,返回值有三个,value:值 type:类型(输入,增加,减少) index(当前组件的索引)
|
|
|
handleChange(value, type) {
|
|
|
if (this.disabled) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this.$emit('change', {
|
|
|
detail: {
|
|
|
value: value,
|
|
|
type: type,
|
|
|
index: this.index
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
<style>
|
|
|
.cl-stepper {
|
|
|
font-size: 0;
|
|
|
}
|
|
|
.cl-stepper__minus,
|
|
|
.cl-stepper__plus {
|
|
|
position: relative;
|
|
|
display: inline-block;
|
|
|
box-sizing: border-box;
|
|
|
margin: 0;
|
|
|
padding: 0;
|
|
|
vertical-align: middle;
|
|
|
border: 0;
|
|
|
background-color: #f7f8fa;
|
|
|
color: #666;
|
|
|
width: 42rpx;
|
|
|
height: 42rpx;
|
|
|
border-radius: 10rpx;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__minus:before,
|
|
|
.cl-stepper__plus:before {
|
|
|
width: 10px;
|
|
|
height: 2px;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__minus:after,
|
|
|
.cl-stepper__plus:after {
|
|
|
width: 2px;
|
|
|
height: 10px;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__minus:after,
|
|
|
.cl-stepper__minus:before,
|
|
|
.cl-stepper__plus:after,
|
|
|
.cl-stepper__plus:before {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
margin: auto;
|
|
|
background-color: currentColor;
|
|
|
content: '';
|
|
|
}
|
|
|
.cl-stepper__minus:active,
|
|
|
.cl-stepper__plus:active {
|
|
|
background-color: #e5e5e5;
|
|
|
}
|
|
|
.cl-stepper__minus--disabled,
|
|
|
.cl-stepper__plus--disabled {
|
|
|
color: #b2b2b2;
|
|
|
background-color: #f7f8fa;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__minus--disabled,
|
|
|
.cl-stepper__minus--disabled.cl-stepper__minus--hover,
|
|
|
.cl-stepper__minus--disabled.cl-stepper__plus--hover,
|
|
|
.cl-stepper__plus--disabled,
|
|
|
.cl-stepper__plus--disabled.cl-stepper__minus--hover,
|
|
|
.cl-stepper__plus--disabled.cl-stepper__plus--hover {
|
|
|
background-color: #f7f8fa;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__minus:after {
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__input {
|
|
|
display: inline-block;
|
|
|
box-sizing: border-box;
|
|
|
min-height: 0;
|
|
|
margin: 1px;
|
|
|
padding: 1px;
|
|
|
text-align: center;
|
|
|
vertical-align: middle;
|
|
|
border: 0;
|
|
|
border-width: 1px 0;
|
|
|
border-radius: 0;
|
|
|
-webkit-appearance: none;
|
|
|
font-size: 14px;
|
|
|
color: #333333;
|
|
|
width: 32px;
|
|
|
height: 28px;
|
|
|
}
|
|
|
|
|
|
.cl-stepper__input--disabled {
|
|
|
color: #c8c9cc;
|
|
|
background-color: #f2f3f5;
|
|
|
}
|
|
|
</style>
|