微信小程序:限制表单多次提交(变量限制+防抖)

方法一:变量限制

设置一个变量,在提交表单前设置为false,当表单开始提交时设置为true(禁用按钮),成功请求或者失败再设置为false

代码

wxml

<form bindsubmit="formSubmit">
  <view class="section">
    <input placeholder="请输入姓名" name="username" />
  </view>
  <view class="section">
    <input type="password" placeholder="请输入密码" name="password" />
  </view>
  <button form-type="submit">提交</button>
</form>

js

const app = getApp()
Page({
  data: {
    isSubmitting: false, // 新增一个表示是否正在提交的状态
  },
  formSubmit: function(e) {
    if (this.data.isSubmitting) return; // 如果正在提交,则不再处理新的提交请求
    // 设置为正在提交状态
    this.setData({ 
      isSubmitting: true 
    }); 
    const forminfo = e.detail.value;
    console.log(forminfo.username+"|"+forminfo.password)
    //发送请求
    wx.request({
      url: app.globalData.position + 'Produce/test',
      data: {
        username: forminfo.username,
        password:forminfo.password
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      method: 'POST',
      dataType: 'json',
      success: res => {
        console.log(res.data)
        this.setData({ isSubmitting: false }); // 请求成功后重置提交状态
        wx.reLaunch({
          url: '/pages/mine/index/index',
        })
      },
      fail(res) {
        console.log("查询失败")
        this.setData({ isSubmitting: false }); // 请求失败后也要重置提交状态
      }
    })
  }
})

方法二:防抖功能

节流(Throttling)和防抖(Debouncing)是两种不同的事件处理优化技术,主要用于限制函数被频繁调用,常用于处理那些高频触发但不需要连续响应的事件,比如窗口 resize、scroll 事件,以及表单提交等场景。
防抖 (Debouncing):
        防抖是指在一个事件持续触发的过程中,只有当这个事件停止触发一段时间后再执行回调函数的操作。举个例子,在监听窗口 resize 事件时,我们不希望在用户连续调整窗口大小的过程中不断触发重绘计算,而是等到用户停止调整尺寸(即一定时间间隔内无新触发)后再执行一次计算。这样可以有效地合并多次操作,减少不必要的计算。
        实现原理: 想象一下按住开关灯会一直闪烁的情景,防抖就像是松开开关后才允许灯亮起,只要手还在按着,不管按了多少次,灯都不会再次亮起,除非松开手并等待一定时间后再次按下。
节流 (Throttling):
        节流则是指在一定时间内无论事件如何触发,都会按照一定的频率执行回调函数,保证了在一段时间内只会被执行一次。这意味着,即使事件连续触发,也会有一定的最小时间间隔来执行回调函数。
        实现原理: 同样以开关灯为例,节流就像是定时开关,即使你快速反复地按开关,灯也只会按照固定的频率(比如每秒钟开关一次)进行切换。
这两种策略在实际应用中可以根据需求选择合适的解决方案。在处理表单提交时,通常采用防抖策略来确保用户在提交按钮被点击后的一段时间内不会重复提交表单;而在滚动事件等场景下,可能更倾向于采用节流策略,确保在用户滚动过程中定期执行某项操作,而不是在滚动停止后再执行。

代码

wxml

<form bindsubmit="formSubmit">
  <view class="section">
    <input placeholder="请输入姓名" name="username" />
  </view>
  <view class="section">
    <input type="password" placeholder="请输入密码" name="password" />
  </view>
  <button form-type="submit">提交</button>
</form>

 js

const app = getApp()
Page({
  data: {
    isSubmitting: false,
    submitTimeoutId: null,
  },

  // 自定义防抖函数
  debounceFn(func, delay) {
    let timer = null;
    return function(...args) {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        func.apply(this, args);
        timer = null;
      }, delay);
    };
  },

  onLoad: function() {
    // 页面加载完成后初始化防抖处理的表单提交方法
    this.formSubmitWrapper = this.debounceFn(this.actualFormSubmit, 1000);
  },

  actualFormSubmit: async function(e) {
    if (this.data.isSubmitting) return;
    this.setData({
      isSubmitting: true,
    });

    const forminfo = e.detail.value;
    console.log(forminfo.username + "|" + forminfo.password);

    try {
      const response = await promisifyRequest({
        url: app.globalData.position + 'Produce/test',
        data: {
          username: forminfo.username,
          password: forminfo.password,
        },
        header: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        method: 'POST',
        dataType: 'json',
      });

      console.log(response.data);
      this.setData({ isSubmitting: false });
      wx.reLaunch({
        url: '/pages/mine/index/index',
      });
    } catch (error) {
      console.error("查询失败", error);
      this.setData({ isSubmitting: false });
    }
  },

  formSubmit: function(e) {
    this.formSubmitWrapper(e);
  },
});

// 将wx.request转换为Promise的形式,用于配合async/await语法
function promisifyRequest(options) {
  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      success: resolve,
      fail: reject,
    });
  });
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值