做表单提交的时候遇到一个问题:表单以及其他的数据提交,如果连续点击提交按钮,不做处理的话会导致同一个表单提交多次到数据库。

一开始想到这个问题,简单,在data函数中定义一个变量然后绑定到按钮的disable属性中
在这里插入图片描述
在这里插入图片描述
点击提交按钮后把disable设为true,这样就会禁用按钮了,然后发出请求提交数据后在回调函数中再把disable改为false
在这里插入图片描述
在这里插入图片描述
大功告成!

但是问题来了
如果后端出现问题导致数据提交失败呢?

由于我在拦截器里加了判断,如果发生错误,程序是不会走到callback函数的,callback函数里处理的主要是提交成功后的提示以及跳转到其他页面,如不设拦截即使提交数据失败也走这个函数显然会有问题,而且其他页面也有用到这个封装好的request方法,所以取消拦截不可取。

所以会出现的现象是:提示用户页面出现问题导致提交未成功,然后因为没有执行callback函数所以按钮的状态还是disable。然而我想实现的是只是防止用户提交多次,无论提交成功与否,我都希望在用户点击提交之后按钮的状态还是可点击的

遂到网上看一下别人是怎么处理的

sendComment () {
      this.disabled = true
      if (this.text == '') {
        this.$message({
          type: 'error',
          message: '输入内容不能为空',
        })
        this.disabled = false
      } else {
        this.$post('/xx/xx/IdleGoodsComment', {
          goods_id: this.$route.params.id,
          content: this.text,
          user_id: window.uId,
          type: 1
        }).then((res) => {
          if (res) {
            this.getDetail()
            setTimeout(() => {
              this.disabled = false
              this.getCommentList()
              this.text = ''            }
              , 2000)
            this.disabled = true
          }
        })
      }
    }

好的,问题解决了,无论成功与否,我的按钮还是会返回到可点击的状态。

但是,又想到一个新的问题,
如果碰到一些网速较慢还有些调皮的用户呢?
点击提交需要好几秒,但我只设了两秒就会返回可点击的状态,然后该用户看到还没提交成功按钮又可以点击了,嗯那我再点一下,然后又回到最初的问题,还是可以提交多次。

不过看到上面的代码,也因此想到一个方法,既然也是用的promise,那我把修改状态的代码放到promise的finally方法中去不就可行了?(finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。)感觉可行,试一下,用着好像没什么问题。
在这里插入图片描述
样式调整,去掉之前的disable,使用vant的Toast组件,点击按钮在发请求前加上Toast组件

Toast.loading({
          message: '正在提交,请勿重复操作',
          forbidClick: true, //是否禁止背景点击
          loadingType: 'spinner',
          duration: 0, //展示时长(ms),值为 0 时,toast 不会消失
        });
        request({
          url: '/care/create',
          method: 'post',

然后在finally里清除掉Toast

finally(() => {
          Toast.clear();
        });

代码

else {
        Toast.loading({
          message: '正在提交,请勿重复操作',
          forbidClick: true,
          loadingType: 'spinner',
          duration: 0,
        });
        request({
          url: '/care/create',
          method: 'post',
          data: {
            id: this.id,
            title,
          },
        }).then(() => {
          Dialog.alert({
            message: '提交成功!',
          }).then(() => {
            this.$router.push('/appointments');
          });
        }).catch(() => {
        }).finally(() => {
          Toast.clear();
        });
Logo

前往低代码交流专区

更多推荐