vue项目防止按钮重复点击(重复请求接口)

3 篇文章 0 订阅

场景

1.保存提交按钮不小心点击了多次。
2.由于网络服务器卡等原因点击事件没有及时响应又点击了一次,造成数据的重复提交和保存,数据的异常。
3.resize、scroll,输入框内容校验等频繁操作。

原因

由于axios提交数据为异步提交,点击提交按钮是通过xmlhttprequest向后端发送异步请求,发送请求后后端返回数据需要时间处理,如果第一次点击的请求尚未完成,又接二连三地提交了几次,同时后面发送的请求都被后台处理了,这种情况如果是读取数据不会有太大影响,但是涉及到数据提交保存或者提交之后多表数据处理就麻烦了,而且此类现象造成的数据都不正常,所以此种情况务必要避免。

解决方法

一.防抖

原理:当第一次触发点击事件时,不会立即执行接口,会等待监听一段时间,若在这段时间没有再次触发该事件,等待时间过后就执行接口。倘若等待时间期间监听到又点击了一次,等待时间随即重置,从最后一次点击事件开始再重新等待这段时间,等待结束后再执行接口。

步骤:

1.创建防抖全局js方法

/**
 * 防抖函数
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行 
 * @return null
 */
let timeout = null;
const debounce = function(func, wait, immediate) {
	// 清除定时器
	if (timeout !== null) clearTimeout(timeout);
	// 立即执行,此类情况一般用不到
	if (immediate) {
		var callNow = !timeout;
		timeout = setTimeout(function() {
			timeout = null;
		}, wait);
		if (callNow) typeof func === 'function' && func();
	} else {
		// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
		timeout = setTimeout(function() {
			typeof func === 'function' && func();
		}, wait);
	}
}

2.具体引用

// 点赞、取消点赞
this.$util.debounce(this.likeCountDelete, 250, true)

缺点:接口操作不是立即调用,需要等待一定时间,倘若时间设置过长,交互感不好。若出现恶意频繁点击不停,接口就会一直反复等待下去一直不会调用。若是现象2的情况,第一次点击后接口返回数据时间过长,一旦超过这个等待时间,按钮再次被点击后还是会出现重复调用的情况。

二.节流

原理:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

步骤:

1.创建节流全局js方法

/**
 * 节流原理:在一定时间内,只能触发一次
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
 let timer, flag;
const throttle = function(func, wait, immediate) {
	if (immediate) {
		if (!flag) {
			flag = true;
			// 如果是立即执行,则在wait毫秒内开始时执行
			typeof func === 'function' && func();
			timer = setTimeout(() => {
				flag = false;
			}, wait);
		}
	} else {
		if (!flag) {
			flag = true
			// 如果是非立即执行,则在wait毫秒内的结束处执行
			timer = setTimeout(() => {
				flag = false
				typeof func === 'function' && func();
			}, wait);
		}
		
	}
};

2.具体引用

// 点赞、取消点赞
this.$util.throttle(this.likeCountDelete, 250, true)

缺点:若是现象2的情况,第一次请求返回时间超过等待的时间,此时再次点击就会再次调用事件接口,造成数据的重复异常

三.按钮禁用控制或者loading

原理:当第一次点击按钮进入事件,按钮状态变为禁用状态,或者打开loading函数进行等待,当请求返回后台数据后按钮再恢复至可点击状态或者loading关闭

// 按钮
<el-button @click="save"  :disabled="disabledFlag">保 存</el-button>

save() {
// 调用接口之前禁用按钮,防止多次点击调用接口
          this.disabledFlag = true
          // 或者打开loading等待
          this.loading.show()
          // 调用接口进行添加填报数据
          api.save({ id: this.id }).then(res => {
            // 接口返回后
            this.disabledFlag = false
            this.loading.hide()
            this.$message({
              type: 'success',
              message: "保存成功!"
            })
          }).catch(() => {
            this.disabledFlag = false
            this.loading.hide()
          })
}

方法虽然笨了点,但是可以完全避免现象2的情况,此方法只有第一次点击调用接口返回数据后才会被点击

  • 7
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值