shop-applet/components/subtractive/subtractive.vue

217 lines
4.3 KiB
Vue
Raw Permalink Normal View History

2024-05-14 17:25:13 +08:00
<template>
<view class="uni-numbox">
<!-- -部分 -->
<view class="uni-numbox-minus" @click="_calcValue('subtract')">
<text :class="minDisabled?'uni-numbox-disabled': ''">-</text>
</view>
<!-- 中间输入数值部分 -->
<input class="uni-numbox-value" type="number" :disabled="disabled" :value="inputValue" @blur="_onBlur">
<!-- + 部分 -->
<view class="uni-numbox-plus" @click="_calcValue('add')">
<text :class="maxDisabled?'uni-numbox-disabled': ''">+</text>
</view>
</view>
</template>
<script>
export default {
name: 'uni-number-box',
props: {
// isMax 是否有上限设置
isMax: {
type: Boolean,
default: false
},
// isMin 是否有下限设置
isMin: {
type: Boolean,
default: false
},
// index 唯一值,如果一个页面有多个数量增减组件时,起到唯一的作用
index: {
type: String,
default: 0
},
// value 是数值
value: {
type: Number,
default: 0
},
// min 最小值
min: {
type: Number,
default: -Infinity
},
// max 最大值
max: {
type: Number,
default: Infinity
},
// step 步长
step: {
type: Number,
default: 1
},
// disabled 是否禁用
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
inputValue: this.value,
minDisabled: false,
maxDisabled: false
}
},
created() {
this.maxDisabled = this.isMax;
this.minDisabled = this.isMin;
},
computed: {
},
watch: {
inputValue(number) {
const data = {
number: number,
index: this.index
}
this.$emit('eventChange', data);
}
},
methods: {
_calcValue(type) {
const scale = this._getDecimalScale();
let value = this.inputValue * scale;
let newValue = 0;
let step = this.step * scale;
if (type === 'subtract') {
newValue = value - step;
if (newValue <= this.min) {
this.minDisabled = true;
}
if (newValue < this.min) {
newValue = this.min
this.$util.Tips({
title: '达到最小值了',
icon: 'error'
})
}
if (newValue < this.max && this.maxDisabled === true) {
this.maxDisabled = false;
}
} else if (type === 'add') {
newValue = value + step;
if (newValue >= this.max) {
this.maxDisabled = true;
}
if (newValue > this.max) {
this.$util.Tips({
title: '达到最大值了',
icon: 'error'
})
newValue = this.max
}
if (newValue > this.min && this.minDisabled === true) {
this.minDisabled = false;
}
}
if (newValue === value) {
return;
}
this.inputValue = newValue / scale;
this.$emit('increment', this.inputValue)
},
_getDecimalScale() {
let scale = 1;
// 浮点型
if (~~this.step !== this.step) {
scale = Math.pow(10, (this.step + '').split('.')[1].length);
}
return scale;
},
_onBlur(event) {
let value = event.detail.value;
if (!value) {
this.inputValue = 0;
return
}
value = +value;
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min
}
this.inputValue = value
}
}
}
</script>
<style>
.uni-numbox {
/* position:absolute; */
/* left: 30upx;
bottom: 0; */
display: flex;
justify-content: flex-start;
align-items: center;
width: 200upx;
height: 50upx;
/* background:#f5f5f5; */
}
.uni-numbox-minus {
background: #EEEEEE !important;
color: #909399 !important;
}
.uni-numbox-minus,
.uni-numbox-plus {
margin: 0;
width: 53rpx;
height: 53rpx;
background-color: #F84221;
opacity: 1;
line-height: 53rpx;
text-align: center;
position: relative;
color: #fff;
font-size: 40upx;
}
.uni-numbox-minus .yticon,
.uni-numbox-plus .yticon {
font-size: 36upx;
color: #555;
}
.uni-numbox-minus {
/* border-right: none;
border-top-left-radius: 6upx;
border-bottom-left-radius: 6upx; */
}
.uni-numbox-plus {
/* border-left: none;
border-top-right-radius: 6upx;
border-bottom-right-radius: 6upx; */
}
.uni-numbox-value {
position: relative;
/* background-color: #f5f5f5; */
width: 90upx;
height: 50upx;
text-align: center;
padding: 0;
font-size: 30upx;
}
.uni-numbox-disabled.yticon {
color: #d6d6d6;
}
</style>