Vue中 實現函數的防抖、節流及應用場景

這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰javascript

1. 簡介

1.1 函數防抖(debounce)css

定義: 在事件被觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時;(相似於 王者榮耀回城效果)java

典型的案例: 輸入搜索:輸入結束後n秒才進行搜索請求,n秒內又輸入的內容,就從新計時。瀏覽器

實現原理: 函數防抖的基本思想是設置一個定時器,在指定時間間隔內運行代碼時清楚上一次的定時器,並設置另外一個定時器,知道函數請求中止並超過期間間隔纔會執行。markdown

使用場景:app

  1. 搜索框搜索輸入,最後一次輸入完成後,再發送請求;
  2. 手機號、郵箱的輸入驗證;
  3. window 觸發 resize 的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次;

1.2 函數節流(throttle)函數

定義: 規定在一個單位時間內,只能觸發一次函數,若是這個單位時間內觸發屢次函數,只有一次生效;post

典型的案例: 鼠標不斷點擊觸發,規定在n秒內屢次點擊只有一次生效。ui

實現原理: 原理是用時間戳來判斷是否已到回調該執行時間,記錄上次執行的時間戳,而後每次觸發 scroll 事件執行回調,回調中判斷當前時間戳距離上次執行時間戳的間隔是否已經到達 規定時間段,若是是,則執行,並更新上次執行的時間戳。this

使用場景:

  1. DOM 元素的拖拽功能實現(mousemove);
  2. 表單的屢次點擊提交;
  3. 計算鼠標移動的距離(mousemove);
  4. Canvas 模擬畫板功能(mousemove);
  5. 射擊遊戲的 mousedown/keydown 事件(單位時間只能發射一顆子彈);
  6. 滾動加載,加載更多的操做;

2. 代碼實現

在Vue2.x中,咱們將防抖和節流函數寫在utils文件夾下方便須要的時候引用

// 防抖
function _debounce(fn, delay = 500) {
  var timer = null;
  return function () {
    var _this = this;
    var args = arguments;
    if (timer) clearTimeout(timer); 
    timer = setTimeout(function () {
      fn.apply(_this, args);
    }, delay);
  };
}

// 節流
function _throttle(fn,delay = 1000){
  var lastTime, timer, delay;
  return function(){
    var _this = this;
    var args = arguments;
    var nowTime = Date.now(); 
    if(lastTime && nowTime - lastTime < delay){
      if (timer) clearTimeout(timer); 
      timer = setTimeout(function(){
        lastTime = nowTime;
        fn.apply(_this,args);
      },delay)
    }else{
      lastTime = nowTime;
      fn.apply(_this,args);
    } 
  }
}  

export {
  _debounce,
  _throttle,
}
複製代碼

組件中引用

<template>
  <div class="about"> <el-input v-model="inputVal" placeholder="請輸入內容" @input="inputChange"></el-input> </div>
</template>

<script> import {_debounce, _throttle} from '@/utils/index.js' export default { data() { return { inputVal:'', count:0, }; }, methods: { // input值改變時觸發 inputChange:_debounce(function(){ console.log(this.inputVal) },1000), // 滾動條滾動時觸發 scroll(){ this.count += 1; console.log('scroll觸發了'+ this.count +'次') } }, mounted() { window.addEventListener('scroll', _throttle(this.scroll,5000)); }, }; </script>

<style lang="stylus" scoped> .about{ width:100%; height:800px; } </style>
複製代碼
相關文章
相關標籤/搜索