在 Vue 中使用lodash對事件進行防抖和節流,防止用戶重復點擊按鈕提交


一、防抖函數手動寫

防抖函數定義:一個需要頻繁觸發的函數,在規定時間內只讓最后一次生效,前面的不生效

/**
 * @param {*} fn 包裝的事件回調函數
 * @param {*} delay 等待時間
 */

export function debounce(fn, delay) {
  // 記錄上一次的延時器
  var timer = null
  // 將debounce處理結果當作函數返回
  return () => {
    // 保留調用時的this上下文
    let context = this
    // 保留調用時傳入的參數
    let args = arguments

    // 每次事件被觸發時,都去清除之前的舊定時器
    if (timer) {
      clearTimeout(timer)
    }
    // 重新設置新的延時器
    timer = setTimeout(() => {
      // 解決this指向問題
      fn.apply(context, args)
    }, delay)
  }
}
// 用debounce來包裝scroll的回調
const better_scroll = debounce(() => console.log('觸發了滾動事件'), 1000)

注意:debounce 的問題在於它“太有耐心了”。試想,如果用戶的操作十分頻繁——他每次都不等 debounce 設置的 delay 時間結束就進行下一次操作,於是每次 debounce 都為該用戶重新生成定時器,回調函數被延遲了不計其數次。頻繁的延遲會導致用戶遲遲得不到響應,用戶同樣會產生“這個頁面卡死了”的觀感

用 Throttle 來優化 Debounce

// fn是我們需要包裝的事件回調, delay是時間間隔的閾值
function throttle(fn, delay) {
  // last為上一次觸發回調的時間, timer是定時器
  let last = 0, timer = null
  // 將throttle處理結果當作函數返回
  
  return function () { 
    // 保留調用時的this上下文
    let context = this
    // 保留調用時傳入的參數
    let args = arguments
    // 記錄本次觸發回調的時間
    let now = +new Date()
    
    // 判斷上次觸發的時間和本次觸發的時間差是否小於時間間隔的閾值
    if (now - last < delay) {
    // 如果時間間隔小於我們設定的時間間隔閾值,則為本次觸發操作設立一個新的定時器
       clearTimeout(timer)
       timer = setTimeout(function () {
          last = now
          fn.apply(context, args)
        }, delay)
    } else {
        // 如果時間間隔超出了我們設定的時間間隔閾值,那就不等了,無論如何要反饋給用戶一次響應
        last = now
        fn.apply(context, args)
    }
  }
}

// 用新的throttle包裝scroll的回調
const better_scroll = throttle(() => console.log('觸發了滾動事件'), 1000)

document.addEventListener('scroll', better_scroll)

 

二、在 Vue 里使用 lodash 中的 Debouncing 和 Throttling

安裝

可以通過 yarn 或 npm 安裝 lodash。

# Yarn
$ yarn add lodash
# NPM
$ npm install lodash --save

注意:如果我們不想導入lodash的所有內容,而只導入所需的部分,則可以通過一些Webpack構建自定義來解決問題。 還可以使用lodash.throttlelodash.debounce等軟件包分別安裝和導入lodash的各個部分。

throttling 方法

要對事件進行節流處理方法非常簡單,只需將要調用的函數包裝在lodash的_.throttle函數中即可。

<template>
  <button @click="throttledMethod()">Click me as fast as you can!</button>
</template>

<script>
import _ from 'lodash'

export default {
  methods: {
    throttledMethod: _.throttle(() => {
      console.log('I get fired every two seconds!')
    }, 2000)
  }
}
</script>

 

debouncing 方法

盡管節流在某些情況下很有用,但一般情況我們經常使用的是防抖。 防抖實質上將我們的事件分組在一起,並防止它們被頻繁觸發。 要在Vue組件中使用節流,只需將要調用的函數包裝在lodash的_.debounce函數中。

 
<template>
  <button @click="throttledMethod()">Click me as fast as you can!</button>
</template>

<script>
import _ from 'lodash'

export default {
  methods: {
    throttledMethod: _.debounce(() => {
      console.log('I only get fired once every two seconds, max!')
    }, 2000)
  }
}
</script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM