我项目的需求是:
1.步进器支持异步加载(先调用接口确定是否有足够库存再决定是否增加/减少);
2.要求步进器支持长按进行数量增加 方便多张购票
3.不允许直接输入数值
4.节流 每次点击触发接口请求的最低毫秒数可控
组件Vue文件 ->
<template>
<!-- 步进器组件 -->
<view class="input-number-mybox">
<button @touchstart.stop.prevent="btnTouchStart('minus')" @touchend.stop.prevent="clearTimer"
:class="[MiunsDis]" :disabled="numberVal<=min" class="minus">
<u-icon size="26" :color="MiunsColor_Dis" name="minus"></u-icon>
</button>
<view class="input-number-box">
<input maxlength="2" disabled="true" class="input-number-class" type="number" :value="numberVal">
</view>
<button @touchstart.stop.prevent="btnTouchStart('add')" @touchend.stop.prevent="clearTimer" :class="[addDis]"
:disabled="numberVal>=max" class="add">
<u-icon size="26" :color="addColor_Dis" name="plus"></u-icon>
</button>
</view>
</template>
<script>
export default {
destroyed() {
console.log('销毁时触发....清理定时器');
this.timer = null;
clearInterval(this.timer);
},
data() {
return {
timer: null, //长按定时器
oneTimer: true, //单击节流
}
},
methods: {
ChangeVal(type) {
//关闭软键盘
uni.hideKeyboard();
//单击节流
if (!this.oneTimer) {
return false
}
//设置为false
this.oneTimer = false;
//多少毫秒执行完毕后 才将状态改为 true
setTimeout(() => {
if (type == 'add') {
let Addnum = Math.floor(Number(this.numberVal + this.step));
if (Addnum > this.max) {
console.log('大于最大值时不触发 并开启下一次点击避免无法 增减')
return this.oneTimer = true;
}
this.$emit('ChangeNumber', Addnum);
} else {
let Minusnum = Math.floor(Number(this.numberVal - this.step));
if (Minusnum < this.min) {
console.log('小于最小值时不触发 并开启下一次点击避免无法 增减')
return this.oneTimer = true;
}
this.$emit('ChangeNumber', Minusnum);
}
this.oneTimer = true;
}, this.longTimer)
},
btnTouchStart(callback) {
//触动 先调用一次增加或者减少方法
console.log('type长按', callback);
this.ChangeVal(callback);
//如果没开启长按功能则直接return
if (!this.longPress) {
return
}
//清空定时器
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
// 执行加或减函数
this.ChangeVal(callback);
}, this.longTimer);
},
clearTimer() {
//松开时立刻清除定时器
this.$nextTick(() => {
console.log('clearTimer...');
clearInterval(this.timer);
this.timer = null;
})
},
},
computed: {
addDis() {
return this.numberVal >= this.max ? 'disabled_use' : ''
},
MiunsDis() {
return this.numberVal <= this.min ? 'disabled_use' : ''
},
MiunsColor_Dis() {
return this.numberVal <= this.min ? 'rgb(200,201,204)' : 'rgb(50,50,51)';
},
addColor_Dis() {
return this.numberVal >= this.max ? 'rgb(200,201,204)' : 'rgb(50,50,51)';
}
},
props: {
//绑定值
numberVal: {
type: [Number, String],
default: 1
},
//控制每次点击增加的量
step: {
type: [Number, String],
default: 1
},
//是否开启按住增加
longPress: {
type: Boolean,
default: true
},
//开启按住增加时 每多少秒触发一次
longTimer: {
type: [Number, String],
default: 600
},
//最小值
min: {
type: [Number, String],
default: 1
},
//最大值
max: {
type: [Number, String],
default: 99999
}
},
}
</script>
<style lang="scss" scoped>
.input-number-mybox {
display: inline-flex;
align-items: center;
width: 212rpx;
.input-number-box {
// flex: 1;
position: relative;
background-color: none;
text-align: center;
background-color: rgb(242, 243, 245);
height: 50rpx;
margin: 0 6rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
.input-number-class {
font-size: 26rpx;
color: rgb(50, 50, 51);
padding: 0;
min-height: 1.4em;
line-height: 1.4em;
}
}
.add,
.minus {
width: 50rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
background-color: #eee;
font-size: 28rpx;
height: 50rpx;
border-radius: 50%;
color: rgb(50, 50, 51);
flex-shrink: 0;
}
.disabled_use {
background-color: rgb(247, 248, 250) !important;
}
}
</style>
父组件使用 参数可参考组件内部注释
<NumberBox :longTimer="450" :numberVal="form.count @ChangeNumber="ChangeNumberCount" />
父组件change事件
async ChangeNumberCount(Val) {
console.log(Val, '传递过来的Val 是否需要修改..');
this.isLoding = true; //开始加载
if (this.form.count <= 0) {
this.form.count = 1;
this.$refs['playmentuToast'].show({
title: '订单数量必须大于0!',
type: 'warning'
})
} else {
//等于1时不需要检查可购买数量
if (Val == 1) {
console.log('等于1时不需要检查可购买数量__');
this.form.count = Val;
}
if (Val > 1) {
//步进器点击增加时 先确认商品是否超出最大可购买数量
let BuyCheck = await goodsBuyCheck(this.goodsId, Val);
if (BuyCheck?.data?.code == 200) {
console.log(BuyCheck, '正常赋值');
this.form.count = Val;
} else {
console.log(BuyCheck, 'notnotnot');
this.$u.toast(BuyCheck.data.message);
this.isLoding = false; //结束加载
return //阻止程序运行
}
}
}
console.log(this.form.count, '监听Change步进器');
await this.findUserCouponListApi(); //获取可用列表优惠券列表
await this.findUserNotCouPonList(); //获取用户不可用优惠券列表
await this.findGoodCouOneApi(); //获取最优优惠券
this.isLoding = false; //结束加载
//调试
// this.debugComputed();
},
目前支持几个我需要用到的参数,其他参数暂未添加 ,单击节流是默认需要的,避免点击太快,如果不想要可以删掉定时器部分代码,仅此做记录。