石广澎
2025-11-17 8771da2ccf6f7c3fd2a8c89a1a0e230c6386db7f
components/input-number/input-number.vue
New file
@@ -0,0 +1,171 @@
<template>
   <view class="count-box" :class="status ? 'count-box-light' : 'count-box-gray'">
      <view class="count-less count-pub" :class="[myValue <= min ? 'light' : '']" @tap.stop="less"></view>
      <view class="u-rela u-flex u-col-center">
         <view class="plc">{{myValue}}</view>
         <input type="number" v-model="myValue" @focus="onFocus" @blur="onBlue" class="count-input" />
      </view>
      <view class="count-add count-pub" :class="[myValue >= max ? 'light' : '']" @tap.stop="add"></view>
   </view>
</template>
<script>
   export default {
      data() {
         return {
            myValue: 0,
            status: false
         }
      },
      props: {
         // 计数器中的值
         value: {
            type: Number,
            default: 0
         },
         max: {
            type: Number,
            default: 10000
         },
         min: {
            type: Number,
            default: 0
         },
         type: {
            type: String,
            default: 'small'
         }
      },
      created() {
         this.myValue = this.value
      },
      watch: {
         value(val) {
            this.myValue = val
         }
      },
      methods: {
         onBlue() {
            if (+this.myValue >= this.max) {
               this.myValue = this.max
               this.status = false
            } else if (+this.myValue <= this.min) {
               this.myValue = this.min
               this.status = false
            } else {
               this.status = true
               this.myValue = +this.myValue
            }
            if (!isNaN(this.myValue)) {
               this.$emit('handleCount', this.myValue)
            } else {
               this.$emit('handleCount', 0)
            }
         },
         onFocus() {
            this.status = true
         },
         add() {
            if (this.myValue >= this.max) {
               this.status = false
               this.myValue = this.max
               uni.showToast({
                  title: "已超过最大积分",
                  icon: "none"
               })
               this.myValue = this.max
            } else {
               this.status = true
               this.myValue++
            }
            this.$emit('handleCount', this.myValue)
         },
         less() {
            if (this.myValue <= this.min) {
               this.status = false
               this.myValue = this.min
               uni.showToast({
                  title: "不能再少了",
                  icon: "none"
               })
               this.myValue = this.min
            } else {
               this.status = true
               this.myValue--
            }
            this.$emit('handleCount', this.myValue)
         }
      }
   }
</script>
<style lang="less" scoped>
   .gray {
      color: #555555;
   }
   .light {
      color: #C8C7CC;
   }
   .count-box {
      display: flex;
      align-items: center;
      height: 60rpx;
   }
   .count-pub {
      width: 42rpx;
      height: 42rpx;
   }
   .count-less {
      left: 0;
      width: 42rpx;
      height: 42rpx;
      background: url(../../static/cart/icon_less.png) no-repeat;
      background-size: 42rpx;
   }
   .count-add {
      right: 0;
      width: 42rpx;
      height: 42rpx;
      background: url(../../static/cart/icon_add.png) no-repeat;
      background-size: 42rpx;
   }
   .count-less.light {
      background: url(../../static/cart/icon_lessLight.png) no-repeat;
      background-size: 42rpx;
   }
   .count-add.light {
      background: url(../../static/cart/icon_addLight.png) no-repeat;
      background-size: 42rpx;
   }
   .count-input {
      position: absolute;
      width: 100%;
      height: 42rpx;
      line-height: 42rpx;
      padding: 0 10rpx;
      box-sizing: border-box;
      color: #333;
      font-size: 30rpx;
      text-align: center;
   }
   .plc {
      height: 42rpx;
      line-height: 1;
      text-align: center;
      min-width: 70rpx;
      font-size: 30rpx;
      padding: 0 12rpx;
      visibility: hidden;
   }
</style>