前端vue中防止用戶短時間內多次點擊按鈕觸發點擊事件解決方法

来源:https://www.cnblogs.com/Steal-cha-of-Melon/archive/2023/01/12/walon_first_title.html
-Advertisement-
Play Games

1.按鈕點擊後添加loading,介面返回成功後再移除loading(經過多次嘗試發現,此方法不能完全確保只調用一次介面,第二次添加時仍會多次調用介面),方法如下: html代碼: <el-button @click="onSave" :loading="onLoading">保存</el-butt ...


1.按鈕點擊後添加loading,介面返回成功後再移除loading(經過多次嘗試發現,此方法不能完全確保只調用一次介面,第二次添加時仍會多次調用介面),方法如下:

 html代碼:

<el-button @click="onSave" :loading="onLoading">保存</el-button>

  javascript代碼:

<script>
export default {
  data() {
    return {
      onLoading: false,
    };
  },
  methods: {
    onSave() {
      this.onLoading = true;
      let parmas = {
        //這裡是介面傳入參數
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {this.$message.success(res.message);
            this.onLoading = false;
          } else {
            this.$message.error(res.message);
            this.onLoading = false;
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

2.在規定時間內禁用按鈕,按鈕無法點擊,即實現介面不被多次調用,方法如下:

 html代碼:

<el-button @click="onSave" :disabled="isdisabled">保存</el-button>

 javascript代碼:

<script>
export default {
  data() {
    return {
      isdisabled: false,
    };
  },
  methods: {
    onSave() {
      this.isdisabled = true;
      //這裡使用定時器解除按鈕禁用
      setTimeout(() => {
        this.isdisabled = false;
      }, 1500);
      let parmas = {
        //這裡是介面傳入參數
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {this.$message.success(res.message);
          } else {
            this.$message.error(res.message);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

3.使用Vue自定義全局指令或局部指令

 html代碼:

<el-button @click="onSave" v-preventReClick>保存</el-button>
  • 自定義全局指令

 javascript代碼:

//使用Vue.directive()來自定義全局註冊指令,在main.js中加入下方這段代碼,可以全局應用
Vue.directive("preventReClick", {
    inserted(el, binding) {
      el.addEventListener("click", () => {
        if (!el.disabled) {
          el.disabled = true;
          setTimeout(() => {
            el.disabled = false;
          }, binding.value || 2000);
        }
      });
    },
  });
  • 自定義局部指令

 javascript代碼:

//在export default {} 中加入下方這段代碼,可以局部應用
directives: {
    preventReClick: {
      // 指令的定義
      inserted(el, binding) {
        el.addEventListener('click', () => {
          if (!el.disabled) {
            el.disabled = true
            setTimeout(() => {
              el.disabled = false
            }, binding.value || 2000)
          }
        })
      }
    }
  }

4.使用節流函數

 節流:是指一種在指定事件防止函數被頻繁調用的思想

 節流函數:是結合時間戳封裝的函數,在指定時間內會調用一次方法

 html代碼:

<el-button @click="getTrottle">保存</el-button>

 javascript代碼:

<script>
const throttle = (func, wait = 50) => {
  //上一次執行該函數的時間
  let lastTime = 0;
  return function (...args) {
    // 當前時間
    let now = +new Date();
    // 將當前時間和上一次執行函數時間對比
    // 如果差值大於設置的等待時間就執行函數
    if (now - lastTime > wait) {
      lastTime = now;
      func.apply(this, args);
    }
  };
};
export default {
  data() {
    return {
      getTrottle: undefined,
    };
  },
  created() {
    this.getTrottle = throttle(this.onSave, 3000);
  },
  methods: {
    onSave() {
      let parmas = {
        //這裡是介面傳入參數
      };
      insert(parmas)
        .then((res) => {
          if (res.code === 200) {
            this.$message.success(res.message);
          } else {
            this.$message.error(res.message);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>

 以上就可以實現了,如果需要多次使用節流函數,也可以封裝後再使用:

// 封裝節流函數
// 參數:1.回調函數,2.時間,3.布爾值
// 時間戳: 毫秒值
// 相差的毫秒值 = 結束的時間戳 - 開始的時間戳
function trottle(callback,times,bool) {
    // 記錄開始的時間戳
    var startTime = new Date().getTime();
    // 記錄布爾值
    var fistFlag = bool;
    // 返回function函數 (事件函數)
    return function() {
        // 記錄結束的時間戳
        var endTime = new Date().getTime();
        // 相差的毫秒值
        var totalTime = endTime - startTime;
        // 記錄事件對象
        var args = arguments[0];
        // 判斷布爾值是否為true
        if(fistFlag){
            if(typeof callback == "function"){
                // 調用回調函數
                callback(args);
                // 設置布爾值為false
                fistFlag = false;
                // 重置開始的時間戳
                startTime = endTime;
            }
        }
        // 判斷是否達到指定的時間
        if(totalTime >= times){
            // 符合條件執行回調函數
            if(typeof callback == "function"){
                // 調用回調函數
                callback(args);
                // 重置開始的時間戳
                startTime = endTime;
            }
        }
    }
}

  以上就是對於用戶短時間內多次點擊按鈕觸發點擊事件的解決方法,哪位小伙伴有其他更簡單的方法歡迎評論留言交流哦~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • AngularJS——初識AngularJS AngularJS是什麼 AngularJS是Google開源的一款前端JS結構化框架,它通過對前端開發進行分層,極好地規範了前端開發的風格——它將前端開發分為Controller層、Service層、DAO層和Model層。其中,Model對象與HTM ...
  • JavaScript 面向切麵編程 (AOP) 是一種編程思想和實現方式,它將一些關註點(例如日誌記錄、安全性檢查、性能監控等)從主題對象中分離出來,通過“橫切關註點”的方式在程式中動態地織入這些關註點。這樣可以避免在主題對象中嵌入大量的關註點代碼,使得代碼更加簡潔和可維護。 ...
  • CSS Grid 佈局是一種二維佈局方式,可以將頁面分成行和列,併在其中放置元素。使用 Grid 佈局時,需要定義網格容器和網格項目。 ...
  • Axios 1.基本說明 Axios是一個基於promise的網路請求庫,作用於node.js和瀏覽器中。它是 isomorphic 的 (即同一套代碼可以運行在瀏覽器和node.js中)。在服務端它使用原生node.js http 模塊, 而在客戶端 (瀏覽端) 則使用XMLHttpRequest ...
  • JavaScript 是一種基於原型繼承的語言。在 JavaScript 中,對象是通過原型鏈來繼承屬性和方法的。 一、原型 每一個對象都有一個 proto 屬性,該屬性指向該對象的原型。原型本質上也是一個對象,所有的對象都擁有一個原型,除了 Object.prototype。 JavaScript ...
  • 著意登樓瞻玉兔,何人張幕遮銀闕?又到了一年一度的網頁小掛件環節,以往我們都是集成別人開源的組件,但所謂熟讀唐詩三百首,不會做詩也會吟,熟讀了別人的東西,做幾首打油詩也是可以的,但若不能自出機抒,卻也成不了大事,所以本次我們從零開始製作屬於自己的網頁小掛件,博君一曬。 玉兔主題元素繪製 成本最低的繪製 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、audio標簽的使用 1、Audio 對象屬性 2、對象方法 二、效果 效果如下: 三、代碼 代碼如下: MusicPlayer.vue <template> <div class="music"> <!-- 占位 --> <div ...
  • 摘要:輸入網址並點回車,後臺到底發生了什麼。透析 HTTP 協議與 TCP 連接之間的千絲萬縷的關係。掌握為何是三次握手四次揮手?time_wait 存在的意義是什麼?全面圖解重點問題,再也不用擔心面試問這個問題。 本文分享自華為雲社區《輸入網址,小手一點,後面到底發生了什麼?》,作者:龍哥手記。 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...