筆記:Vue中防抖(debounce)、節流(throttle)的介紹與運用
阿新 • • 發佈:2022-05-11
1.防抖(debounce) 在事件被觸發n秒後再執行回撥,如果在這n秒內又被觸發,則重新計時;典型的案例就是輸入搜尋:輸入結束後n秒才進行搜尋請求,n秒內又輸入的內容,就重新計時。 通俗理解,就是我們在點選請求或者點選載入等過程中,只需要點選一次,但由於請求慢,點選了好多次,導致多次請求,防抖就是在點選了好多次之後的最後一次才會請求。 在一些搜尋框輸入內容時,會有好多聯想詞在下方顯示出來,並不是輸入框內容一改變就觸隨即彈出聯想詞的,是我們結束輸入後,經過一段時間,才會觸發。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>防抖</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> 輸入內容:<input type="text" class="input" @keyup="deb"/> <div> 輸入次數:{{num}}</div> </div> <script> let time var app=new Vue({ el:'#app', data:{ num:0, }, methods:{ deb: function () { let that = this if (time) { clearTimeout(time) } time = setTimeout(function () { that.num++ console.log('輸入了'+that.num+'次') time = undefined; }, 2000) } } }) </script> </body> </html>
輸入一次文字2秒後執行,多次輸入,還是執行一次,輸入次數只加1
搭配鍵盤修飾符:(.enter為例) <div id="app"> 輸入內容:<input type="text" class="input" @keyup.enter="deb"/> <div> 輸入次數:{{num}}</div> </div> 這樣連續按回車後,也只會觸發一次 輸入 ,每次按回車間隔設定的兩秒,才會觸發一次。 所以,考慮到會出現連續點選了提交按鈕,連續觸控的情況,防抖是很有必要的。 當然,也有另外的解決方式,比如專案裡用的是控制按鈕的方式,點選儲存,在請求介面返回200之前,按鈕禁止使用,這裡就不會出現重複點選了。
2.節流(throttle) 規定在一個單位時間內,只能觸發一次函式,如果這個單位時間內觸發多次函式,只有一次生效; 典型的案例就是滑鼠不斷點選觸發,規定在n秒內多次點選只有一次生效。 在某應用購買火車票/飛機票等商品的時候,不斷地點選重新整理購買,總不能一直點選一直請求吧,系統會崩掉的,所以節流就很有必要了。 咦?怎麼感覺和防抖很像? 區別來了:防抖動是將多次執行變為最後一次執行,節流是將多次執行變成每隔一段時間執行。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>節流</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <button @click="thr">點選</button> <div>實際點選:{{clicknumber}}</div> <div>有效點選:{{num}}</div> </div> <script> let time let lastTime var app=new Vue({ el:'#app', data:{ num:0, clicknumber:0 }, methods: { thr: function () { this.clicknumber++ let that = this let now = new Date(); if (lastTime && now - lastTime < 2000) { clearTimeout(time) } time = setTimeout(function () { that.num++ console.log('點選了'+that.num+'次') lastTime = new Date() }, 500) } } }) </script> </body> </html>
(在連續點選的情況下,每隔一段時間,才會有效點選一次) 當點選一次的時候,if語句不滿足條件,設定定時器,num++ ;如果隨後快速點選了第二次:兩種情況,(1) now - lastTime < 2000 時候,清除定時器,點選無意義. (2)now - lastTime >= 2000 定時器覆蓋,num++ 點選有效.