自学内容网 自学内容网

vue3 uiapp实现一个数字输入组件, 输入非数字会默认转成最小数

实现一个数字输入组件

用户输入字符串、汉字、字母等非数字,会默认转成最小数
使用vue3 最新语法defineModel

<template>
  <view class="number-box">
    <view 
      class="number-btn minus" 
      :class="{ disabled: disabled || model <= min }"
      @click="handleMinus"
    >-</view>
    
    <input
      type="number"
      class="number-input"
      v-model="inputValue"
      :disabled="disabled"
     
      @blur="handleBlur"
    />
    
    <view 
      class="number-btn plus"
      :class="{ disabled: disabled || model >= max }"
      @click="handlePlus"
    >+</view>
  </view>
</template>

<script setup>
import { ref, toRefs, onMounted } from 'vue'

const model = defineModel()
const props = defineProps({
  min: {
    type: Number,
    default: 0
  },
  max: {
    type: Number,
    default: 100
  },
  step: {
    type: Number,
    default: 1
  },
  disabled: {
    type: Boolean,
    default: false
  }
})

const { min, max, step, disabled } = toRefs(props)
const emit = defineEmits(['change'])
const inputValue=ref(model.value || props.min)
const getDecimalScale = () => {
let scale = 1
// 浮点型
if (~~props.step !== props.step) {
scale = Math.pow(10, String(props.step).split(".")[1].length)
}
return scale
}
// 添加
const handlePlus=()=>{

if(model.value>=max.value) return
model.value=model.value+step.value
 emit('change', model.value)
}
const handleMinus=()=>{

if(model.value<=min.value||model.value<=0) return
model.value=model.value-step.value
  emit('change', model.value)
}

// 失去焦点
const handleBlur=(e)=>{
// console.log(e)

let value = e.detail.value
if (isNaN(value)) {
inputValue.value = props.min
model.value = props.min
return
}
value = +value
if (value > props.max) {
value = props.max
} else if (value < props.min) {
value = props.min
}
const scale = getDecimalScale()
const newValue = Number(value.toFixed(String(scale).length - 1))
inputValue.value = newValue
model.value = newValue
 emit('change', model.value)
}
watch(()=>model.value,(newVal)=>{
if (newVal !== undefined && newVal !== null) {
inputValue.value = +newVal
}
})
onMounted(() => {
if (model.value !== undefined && model.value !== null) {
inputValue.value = +model.value
}
})
</script>

<style lang="scss" scoped>
.number-box {
  display: flex;
  align-items: center;
  width: fit-content;
  background: #fff;
  border-radius: 6rpx;
  
  .number-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60rpx;
    height: 60rpx;
    background: #F8F9FA;
    color: #333;
    font-size: 28rpx;
    
    &.disabled {
      opacity: 0.5;
      background: #eee;
    }
    
    &.minus {
      border-radius: 6rpx 0 0 6rpx;
    }
    
    &.plus {
      border-radius: 0 6rpx 6rpx 0;
    }
    
    &:active:not(.disabled) {
      background: #e0e0e0;
    }
  }
  
  .number-input {
    margin: 0 20rpx;
    width: 80rpx;
    height: 60rpx;
    text-align: center;
    font-size: 28rpx;
    background-color: #F8F9FA;
    
    &:disabled {
      background: #f5f5f5;
      color: #999;
    }
  }
}
</style> 

组件使用

easycom 可以放到根目录components 创建文件和文件夹同名的组件,
页面中就可以直接使用目录名称即可

<mNumberBox v-model="value"
:min="1"
:max="100"
:step="1"
@change="handleChange"
></mNumberBox>

最小值 min
最大值max
每次加减值 step
change 数字改变后传的值
v-model  双向绑定值

原文地址:https://blog.csdn.net/u010843503/article/details/145154245

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!