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

方法一:变量限制

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

代码

wxml

html 复制代码
<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

javascript 复制代码
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

html 复制代码
<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

javascript 复制代码
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,
    });
  });
}
相关推荐
HerayChen38 分钟前
微信小程序混合 h5 wx.miniProgram是 undefined
微信小程序·小程序·h5
耶啵奶膘5 小时前
uniapp+vue2全局监听退出小程序清除缓存
小程序·uni-app
中云DDoS CC防护蔡蔡7 小时前
微信小程序被攻击怎么选择高防产品
服务器·网络安全·微信小程序·小程序·ddos
井眼11 小时前
微信小程序-prettier 格式化
微信小程序·小程序
qq_174482857513 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
wqq_99225027713 小时前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
licy__19 小时前
微信小程序登录注册页面设计(小程序项目)
微信小程序·小程序
wqq_9922502771 天前
springboot基于微信小程序的农产品交易平台
spring boot·后端·微信小程序
说私域2 天前
基于“开源 2+1 链动模式 S2B2C 商城小程序”的社区团购运作主体特征分析
大数据·人工智能·小程序
HUODUNYUN2 天前
小程序免备案:快速部署与优化的全攻略
服务器·网络·web安全·小程序·1024程序员节