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