vue项目怎么阻止很快速的点击两次然后提交的两次请求

像提交表单类似的数据的时候,连续点击两次会出现提交两次请求,前端有没有全局的js去控制这个?

阅读 24.4k
4 个回答

方案一:申明一个变量,点击时置灰提交按钮。等接口调用结束放开按钮。

<template>
<div>
    <!-- 其他代码 -->
    <button v-if="canSave" @click="save">提交</button>
    <button v-else disabled>提交</button>
</div>
</template>
<script>
export default {
    data(){
        return {
            canSave: true,
        }
    },
    methods: {
        save(){
            if(!canSave){
                return;
            }
            this.canSave = false;
            // AJAX 结束后 this.canSave = true;
        },
    }
}
</script>

方案二:加防抖。放几个之前收藏的链接:
JavaScript 函数节流和函数去抖应用场景辨析
underscore 函数去抖的实现
underscore 函数节流的实现

JavaScript专题之跟着underscore学防抖
JavaScript专题之跟着 underscore 学节流

  1. debouncethrottle是目前用得最广泛的,具体可见楼上的一堆收藏;
  2. 想要确保逻辑上不会有同时提交的请求,npm搜“mutex”也有很多;
  3. 或者我也写了一个简易版的,用下面的函数包裹点击回调,如果前一次请求尚未结束,新请求会和旧请求一起返回。这样的话回调要返回Promise

    const debounceAsync = originalFunction => {
      let currentExcution = null;
      const wrappedFunction = async function () {
        // 1. locked => return lock
        if (currentExcution) return currentExcution;
    
        // 2. released => apply
        currentExcution = originalFunction.apply(this, arguments);
        try {
          return await currentExcution;
        }
        finally {
          currentExcution = null;
        }
      };
      return wrappedFunction;
    };

    用法

    const sleep = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));
    
    const debounceAsync_UNIT_TEST = async () => {
      const goodnight = debounceAsync(sleep);
      for (let i = 0; i < 8; i++) {
        goodnight(5000).then(() => console.log(Date()));
        await sleep(500);
      }
      console.warn('Expected output: 8 identical datetime');
    };

    https://segmentfault.com/a/11...

现在比较好的处理就是你在点击之后,ajax请求完成之前将那个按钮禁止点击。

其实所有的接口请求都有这个需求,因此可以对ajax封装一个代理层

代理层可以做两个事情

  1. 缓存接口返回数据,可以缓存到sessionstorage,也可以缓存到内存,相同的请求先访问缓存
  2. 给每个请求接口加状态,未请求、请求中、已完成。未请求时去请求接口,同时把此接口状态置为请求中;请求中时再请求接口,将回调保存起来,接口数据返回以后,将数据存储到缓存,一起回调;已完成时请求接口,直接从缓存中读取数据,不再请求接口

这样,不光是vue项目,也不光是post或者提交表单,所有的接口请求都具备了你需要的能力。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏