vue函數防抖與節(jié)流的正確使用方法
前言
1、防抖(debounce):觸發(fā)高頻事件后 n 秒內函數只會執(zhí)行一次,如果 n 秒內高頻事件再次被觸發(fā),則重新計算時間
舉例:就好像在百度搜索時,每次輸入之后都有聯(lián)想詞彈出,這個控制聯(lián)想詞的方法就不可能是輸入框內容一改變就觸發(fā)的,他一定是當你結束輸入一段時間之后才會觸發(fā)。
節(jié)流(thorttle):高頻事件觸發(fā),但在 n 秒內只會執(zhí)行一次,所以節(jié)流會稀釋函數的執(zhí)行頻率
舉例:預定一個函數只有在大于等于執(zhí)行周期時才執(zhí)行,周期內調用不執(zhí)行。就好像你在淘寶搶購某一件限量熱賣商品時,你不斷點刷新點購買,可是總有一段時間你點上是沒有效果,這里就用到了節(jié)流,就是怕點的太快導致系統(tǒng)出現(xiàn)bug。
2、區(qū)別:防抖動是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變成每隔一段時間執(zhí)行。
函數的防抖與節(jié)流是一直的面試話題。對于函數防抖與節(jié)流的寫法,大家都可能比較熟悉,但是在vue中使用函數的防抖或者節(jié)流,這里是有一個小插曲的哦。
vue中的正確使用姿勢

在這個地方相信好多人的使用方式,會直接定義函數,然后在函數中使用debounce的 ,這樣的使用方法是錯誤的。

為啥呢?這個和vue的事件綁定原理有關,這里不詳細介紹。如果直接在函數體內部使用的話,最后的結果是,一個匿名的立即執(zhí)行函數來進行執(zhí)行,這樣是不對的。詳細參考
原理
函數的防抖
函數的防抖是在多少時間后再來執(zhí)行函數,我們可以理解為這樣的一種生活場景(坐升降電梯),在點擊電梯的開門按鈕后,電梯會開門,然后等待一段時間來關門。但是如果在等待的期間,有人再次點擊開門按鈕,那么電梯后繼續(xù)等待關門時間,直到等待關門時間結束,沒有人來點擊開門按鈕后,電梯才會開始工作。
代碼書寫
第一次非立即執(zhí)行
export function debounce(f, t){
let timer;
return (...arg) => {
clearTimeout(timer);
timer = setTimeout(() =>{
f( ...arg)
}, t)
}
}

第一次立即執(zhí)行
對于有些場景來說,第一次我不需要等待,需要立即執(zhí)行,例如:打開控制臺獲取窗口試圖大?。ㄟ@里我們需要一直改變窗口的大小,等停下來再次獲取窗口視圖大?。?/p>
export function debounceFirstExe(f, t){
let timer, flag = true;
return (...args) => {
if (flag){
f(...args);
flag = false;
}else {
clearTimeout(timer);
timer = setTimeout(() => {
f(...args);
flag = true;
}, t)
}
}
}

合并版本
export function debounce(f, t,im = false){
let timer, flag = true;
return (...args) => {
// 需要立即執(zhí)行的情況
if (im){
if (flag){
f(...args);
flag = false;
}else {
clearTimeout(timer);
timer = setTimeout(() => {
f(...args);
flag = true
}, t)
}
}else {
// 非立即執(zhí)行的情況
clearTimeout(timer);
timer = setTimeout(() => {
f(...args)
}, t)
}
}
}

函數防抖對于我們代碼層面我們可以用在哪里呢?
在點贊、輸入框校驗、取消點贊、創(chuàng)建訂單等發(fā)送網絡氫氣的時候,如果我們連續(xù)點擊按鈕,可能會發(fā)送多次請求。這個對于后臺來說是不允許的。在鼠標每次 resize/scroll 觸發(fā)統(tǒng)計事件。
函數節(jié)流
與函數防抖的胞兄,函數節(jié)流的原理也是大同小異,函數節(jié)流是在一定時間內我只會執(zhí)行一次。
第一次非立即執(zhí)行
export function throttle(f,t){
let timer=true;
return (...arg)=>{
if(!timer){
return;
}
timer=false;
setTimeout(()=>{
f(...arg);
timer=true;
},t)
}
}

在效果中,我們點擊了非常多次,但是就只執(zhí)行了4次,因為我規(guī)定的時間是1000ms執(zhí)行一次。這樣也是減少了執(zhí)行次數。
第一次立即執(zhí)行版本
export function throttleFirstExt(f, t) {
let flag = true;
return (...args) => {
if (flag) {
f(...args);
flag = false;
setTimeout(() => {
flag = true
}, t)
}
}
}

這里我們看到了,第一次點擊會立馬執(zhí)行。
合并版
export function throttle(f, t, im = false){
let flag = true;
return (...args)=>{
if(flag){
flag = false
im && f(...args)
setTimeout(() => {
!im && f(...args)
flag = true
},t)
}
}
}

應用場景:
- DOM 元素的拖拽功能實現(xiàn)(mousemove)
- 搜索聯(lián)想(keyup)
- 計算鼠標移動的距離(mousemove)
- Canvas 模擬畫板功能(mousemove)
- 射擊游戲的 mousedown/keydown 事件(單位時間只能發(fā)射一顆子彈)
- 監(jiān)聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 后,只有用戶停止?jié)L動后,才會判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次.
總結
到此這篇關于vue函數防抖與節(jié)流正確使用的文章就介紹到這了,更多相關vue函數防抖與節(jié)流內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue uniapp 防止按鈕多次點擊的三種實現(xiàn)方式
最近的項目完成后,在性能優(yōu)化階段需要做按鈕的防止重復點擊功能,本文主要介紹了vue uniapp 防止按鈕多次點擊的三種實現(xiàn)方式,具有一定的參考價值,感興趣的可以了解一下2023-08-08
vue如何使用element ui表格el-table-column在里面做判斷
這篇文章主要介紹了vue如何使用element ui表格el-table-column在里面做判斷問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
vue-print-nb解決vue打印問題,并且隱藏頁眉頁腳方式
這篇文章主要介紹了vue-print-nb解決vue打印問題,并且隱藏頁眉頁腳方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動效果
使用postgres(postgis)數據庫以及nodejs作為后臺,vue和openlayers做前端,openlayers使用http請求通過nodejs從postgres數據庫獲取數據,這篇文章主要介紹了vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動,需要的朋友可以參考下2024-05-05
Vue2中如何使用全局事件總線實現(xiàn)任意組件間通信
全局事件總線就是一種組件間通信的方式,適用于任意組件間通信,下面這篇文章主要給大家介紹了關于Vue2中如何使用全局事件總線實現(xiàn)任意組件間通信的相關資料,需要的朋友可以參考下2022-12-12
關于el-table表格組件中插槽scope.row的使用方式
這篇文章主要介紹了關于el-table表格組件中插槽scope.row的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

