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

方法一:变量限制

设置一个变量,在提交表单前设置为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,
    });
  });
}
相关推荐
2501_916008898 分钟前
iOS 不上架怎么安装?多种应用分发方式解析,ipa 文件安装、企业签名、Ad Hoc 与 TestFlight 实战经验
android·macos·ios·小程序·uni-app·cocoa·iphone
CRMEB定制开发3 小时前
PHP多商户接入阿里云识图找商品
android·阿里云·小程序·php·商城系统·微信商城·crmeb
00后程序员张3 小时前
iOS App 混淆实战,在源码不可用情况下的成品加固与测试流程
android·ios·小程序·https·uni-app·iphone·webview
说私域5 小时前
基于开源AI智能名片与链动2+1模式的S2B2C商城小程序研究:构建“信息找人”式精准零售新范式
人工智能·小程序·开源
知识分享小能手5 小时前
微信小程序入门学习教程,从入门到精通,微信小程序页面交互 —— 知识点详解与案例实现(3)
前端·javascript·学习·react.js·微信小程序·小程序·交互
说私域6 小时前
开源AI智能名片链动2+1模式S2B2C商城小程序在公益课裂变法中的应用与影响研究
人工智能·小程序
Tartly6 小时前
掌中智汇,运筹帷幄 - 全新ASUS华硕智汇商擎小程序上线
小程序
私人珍藏库6 小时前
[吾爱大神原创] wx小程序自动解包工具界面版1.0.0
小程序
编程乐学6 小时前
小程序原创--基于微信开发者工具实现的猜谜游戏程序
微信小程序·课程设计·小游戏·微信开发者工具·课设·猜谜游戏·小程序大作业
2501_916013747 小时前
iOS 26 设备文件管理实战指南,文件访问、沙盒导出、系统变更与 uni-app 项目适配
android·ios·小程序·uni-app·cocoa·iphone·webview