daShangDao_miniProgram/components/PriceStockControl.vue
2025-11-24 10:25:20 +08:00

227 lines
5.2 KiB
Vue

<template>
<view class="price-stock-container">
<!-- 价格控制 -->
<view class="control-item">
<view class="section-header">
<text class="section-title">价格</text>
</view>
<view class="number-control-wrapper">
<text class="number-control-btn minus-btn" @click="decreasePrice">-</text>
<input type="digit" v-model="priceValue" class="custom-input-box" @blur="validatePrice"
:disabled="disabled" />
<text class="number-control-btn plus-btn" @click="increasePrice">+</text>
</view>
</view>
<!-- 库存控制 -->
<view class="control-item">
<view class="section-header">
<text class="section-title">库存</text>
</view>
<view class="number-control-wrapper">
<text class="number-control-btn minus-btn" @click="decreaseStock">-</text>
<input type="digit" v-model="stockValue" class="custom-input-box" @blur="validateStock"
:disabled="disabled" />
<text class="number-control-btn plus-btn" @click="increaseStock">+</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'PriceStockControl',
props: {
// 价格值
price: {
type: [Number, String],
default: 1.00
},
// 库存值
stock: {
type: [Number, String],
default: 1
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 价格变化步长
priceStep: {
type: Number,
default: 0.01
},
// 库存变化步长
stockStep: {
type: Number,
default: 1
}
},
data() {
return {
priceValue: this.price,
stockValue: this.stock
}
},
watch: {
// 监听外部价格变化
price(newVal) {
this.priceValue = newVal;
},
// 监听外部库存变化
stock(newVal) {
this.stockValue = newVal;
},
// 监听内部价格变化,触发父组件更新
priceValue(newVal) {
this.$emit('update:price', newVal);
},
// 监听内部库存变化,触发父组件更新
stockValue(newVal) {
this.$emit('update:stock', newVal);
}
},
methods: {
// 增加价格值
increasePrice() {
if (parseFloat(this.priceValue) < 999) {
this.priceValue = parseFloat((parseFloat(this.priceValue) + this.priceStep).toFixed(2));
this.$emit('priceChange', this.priceValue);
}
},
// 减少价格值
decreasePrice() {
if (parseFloat(this.priceValue) > this.priceStep) {
this.priceValue = parseFloat((parseFloat(this.priceValue) - this.priceStep).toFixed(2));
this.$emit('priceChange', this.priceValue);
}
},
// 验证价格值
validatePrice() {
let val = parseFloat(this.priceValue);
if (isNaN(val)) {
this.priceValue = 0;
} else if (val > 99999) {
this.priceValue = 99999;
} else if (val < 0) {
this.priceValue = 0;
} else {
this.priceValue = parseFloat(val.toFixed(2));
}
this.$emit('priceChange', this.priceValue);
},
// 增加库存值
increaseStock() {
if (parseFloat(this.stockValue) < 99) {
this.stockValue = parseFloat((parseFloat(this.stockValue) + this.stockStep).toFixed(0));
this.$emit('stockChange', this.stockValue);
}
},
// 减少库存值
decreaseStock() {
if (parseFloat(this.stockValue) > this.stockStep) {
this.stockValue = parseFloat((parseFloat(this.stockValue) - this.stockStep).toFixed(0));
this.$emit('stockChange', this.stockValue);
}
},
// 验证库存值
validateStock() {
let val = parseFloat(this.stockValue);
if (isNaN(val)) {
this.stockValue = 0;
} else if (val > 99999) {
this.stockValue = 99999;
} else if (val < 0) {
this.stockValue = 0;
} else {
this.stockValue = parseInt(val);
}
this.$emit('stockChange', this.stockValue);
},
// 重置价格和库存到默认值
reset() {
console.log('PriceStockControl组件重置');
this.priceValue = 1.00;
this.stockValue = 1;
this.$emit('priceChange', this.priceValue);
this.$emit('stockChange', this.stockValue);
this.$emit('update:price', this.priceValue);
this.$emit('update:stock', this.stockValue);
return true;
}
}
}
</script>
<style scoped>
/* 价格和库存容器 */
.price-stock-container {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 10rpx;
gap: 60rpx;
/* gap: 20rpx; */
}
.control-item {
display: flex;
align-items: center;
}
.section-header {
margin-right: 10rpx;
}
.section-title {
font-size: 28rpx;
color: #333;
}
/* 控制按钮基础样式 */
.number-control-btn {
width: 36rpx;
height: 36rpx;
background-color: #f2f2f2;
border-radius: 4rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #666;
cursor: pointer;
}
.number-control-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10rpx;
}
.minus-btn,
.plus-btn {
padding: 0 10rpx;
font-size: 24rpx;
border: 1rpx solid #ccc;
border-radius: 4rpx;
background: #fff;
height: 36rpx;
line-height: 36rpx;
min-width: 32rpx;
text-align: center;
}
.custom-input-box {
width: 120rpx;
text-align: center;
border: 1rpx solid #eee;
border-radius: 4rpx;
height: 36rpx;
line-height: 36rpx;
margin: 0 5rpx;
background-color: #f8f8f8;
font-size: 30rpx;
}
</style>