You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
5.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>