前端vue中防止用户短时间内多次点击按钮触发点击事件解决方法

1.按钮点击后添加loading,接口返回成功后再移除loading(经过多次尝试发现,此方法不能完全确保只调用一次接口,第二次添加时仍会多次调用接口),方法如下:

 html代码:

<el-button @click="onSave" :loading="onLoading">保存</el-button>

  javascript代码:

<script>
export default {
  data() {
    return {
      onLoading: false,
    };
  },
  methods: {
    onSave() {
      this.onLoading = true;
      let parmas = {
        //这里是接口传入参数
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {this.$message.success(res.message);
            this.onLoading = false;
          } else {
            this.$message.error(res.message);
            this.onLoading = false;
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

2.在规定时间内禁用按钮,按钮无法点击,即实现接口不被多次调用,方法如下:

 html代码:

<el-button @click="onSave" :disabled="isdisabled">保存</el-button>

 javascript代码:

<script>
export default {
  data() {
    return {
      isdisabled: false,
    };
  },
  methods: {
    onSave() {
      this.isdisabled = true;
      //这里使用定时器解除按钮禁用
      setTimeout(() => {
        this.isdisabled = false;
      }, 1500);
      let parmas = {
        //这里是接口传入参数
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {this.$message.success(res.message);
          } else {
            this.$message.error(res.message);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

3.使用Vue自定义全局指令或局部指令

 html代码:

<el-button @click="onSave" v-preventReClick>保存</el-button>
  • 自定义全局指令

 javascript代码:

//使用Vue.directive()来自定义全局注册指令,在main.js中加入下方这段代码,可以全局应用
Vue.directive("preventReClick", {
    inserted(el, binding) {
      el.addEventListener("click", () => {
        if (!el.disabled) {
          el.disabled = true;
          setTimeout(() => {
            el.disabled = false;
          }, binding.value || 2000);
        }
      });
    },
  });
  • 自定义局部指令

 javascript代码:

//在export default {} 中加入下方这段代码,可以局部应用
directives: {
    preventReClick: {
      // 指令的定义
      inserted(el, binding) {
        el.addEventListener('click', () => {
          if (!el.disabled) {
            el.disabled = true
            setTimeout(() => {
              el.disabled = false
            }, binding.value || 2000)
          }
        })
      }
    }
  }

4.使用节流函数

 节流:是指一种在指定事件防止函数被频繁调用的思想

 节流函数:是结合时间戳封装的函数,在指定时间内会调用一次方法

 html代码:

<el-button @click="getTrottle">保存</el-button>

 javascript代码:

<script>
const throttle = (func, wait = 50) => {
  //上一次执行该函数的时间
  let lastTime = 0;
  return function (...args) {
    // 当前时间
    let now = +new Date();
    // 将当前时间和上一次执行函数时间对比
    // 如果差值大于设置的等待时间就执行函数
    if (now - lastTime > wait) {
      lastTime = now;
      func.apply(this, args);
    }
  };
};
export default {
  data() {
    return {
      getTrottle: undefined,
    };
  },
  created() {
    this.getTrottle = throttle(this.onSave, 3000);
  },
  methods: {
    onSave() {
      let parmas = {
        //这里是接口传入参数
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {
            this.$message.success(res.message);
          } else {
            this.$message.error(res.message);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

 以上就可以实现了,如果需要多次使用节流函数,也可以封装后再使用:

// 封装节流函数
// 参数:1.回调函数,2.时间,3.布尔值
// 时间戳: 毫秒值
// 相差的毫秒值 = 结束的时间戳 - 开始的时间戳
function trottle(callback,times,bool) {
    // 记录开始的时间戳
    var startTime = new Date().getTime();
    // 记录布尔值
    var fistFlag = bool;
    // 返回function函数 (事件函数)
    return function() {
        // 记录结束的时间戳
        var endTime = new Date().getTime();
        // 相差的毫秒值
        var totalTime = endTime - startTime;
        // 记录事件对象
        var args = arguments[0];
        // 判断布尔值是否为true
        if(fistFlag){
            if(typeof callback == "function"){
                // 调用回调函数
                callback(args);
                // 设置布尔值为false
                fistFlag = false;
                // 重置开始的时间戳
                startTime = endTime;
            }
        }
        // 判断是否达到指定的时间
        if(totalTime >= times){
            // 符合条件执行回调函数
            if(typeof callback == "function"){
                // 调用回调函数
                callback(args);
                // 重置开始的时间戳
                startTime = endTime;
            }
        }
    }
}

5.使用Vue事件修饰符

<el-button v-on:click.once="onSave" :loading="onLoading">保存</el-button>

 

热门相关:帝少的专属:小甜心,太缠人   苏醒的秘密   薄先生,情不由己   天启预报   豪门闪婚:帝少的神秘冷妻